Taste Match

official

Reserve and find restaurants easily - in and around Switzerland only

What can you do with Taste Match MCP?

  • Count matches first — Ask how many venues fit a filter set before pulling rows, using count_restaurants.
  • Filter by facets — Search venues by location, opening day or service, cuisine, menu and drink options, or bookability with filter_restaurants.
  • Find a named dish — Search menus for a dish in the guest's own wording and see which venues serve it via search_dishes.
  • Look up a venue by name — Find restaurants by name or what they are called, optionally bounded to a region, with search_restaurants.
  • Get popular picks — List the most-liked venues in a given region with list_popular_restaurants.
  • Find similar places — Get venues close in taste to one you already have a key for, using list_similar_restaurants.

Hosted MCP Server

npx add-mcp 'https://mcp.tastematch.io/'

Installs into Claude Code, Codex, Cursor and more

Documentation

Public service URLhttps://mcp.tastematch.io/
Privacy statement URLhttps://tastematch.io/mcp/privacy.html

Streamable HTTP MCP Toolkit helping you find your most fitting restaurants in Switzerland & farther afield. Add it to an MCP client using the URL above. Discovery is public.

AUTHENTICATION

To access our MCP server, your service will need to self-register using DCR (OAuth 2.0 Dynamic Client Registration) at the authorization server named under authorization_servers in /.well-known/oauth-protected-resource/mcp; that server's own metadata document carries the registration_endpoint.

To support authenticated endpoints, your users will have to authenticate against the same authorization server with OpenID Connect (authorization code with PKCE), requesting what scopes_supported in /.well-known/oauth-protected-resource/mcp lists.

  • 🟢 No sign-in: the tool answers anyone.
  • 🟡 Sign-in for some arguments, e.g. list_recommended_restaurants resolve_key. Otherwise public calls, which allow user-specific params; use of these params succeeds only when logged in. See below for login failure.
  • 🔴 Sign-in: the tool acts for a user. Users may be anonymous. Called without a token it is answered HTTP 401 with a WWW-Authenticate challenge pointing at /.well-known/oauth-protected-resource/mcp, and the client signs the person in with OAuth (authorization code with PKCE). The signed-in person is the identity.
  • Rung: anonymous is anyone signed in. reservation adds a first and last name, one contact and accepted Terms, which promote_identity collects when a booking needs them.
  • Rate limit: calls are counted per signed-in person, and every caller without a token shares one budget. A call over the limit is refused with a code; wait, then send fewer.

DISCOVER

🟢 count_restaurants read How many venues a facet set matches, with no rows. Call this before filter_restaurants when exploring a filter space: it answers the same question without the documents.

Count restaurants

How many venues a facet set matches, with no rows. Call this before filter_restaurants when exploring a filter space: it answers the same question without the documents.

ParameterTypeDescription
drinkOptionsobjectwhat the drinks list must carry
drinkOptions.beerSelectionbooleantrue narrows to venues carrying it; omit it to not narrow on it
drinkOptions.cocktailSelectionbooleantrue narrows to venues carrying it; omit it to not narrow on it
drinkOptions.natureWineSelectionbooleantrue narrows to venues carrying it; omit it to not narrow on it
drinkOptions.wineSelectionbooleantrue narrows to venues carrying it; omit it to not narrow on it
kitchenobjectthe kitchen it cooks
kitchen.cuisinearray<string>cuisine slugs, any one of which satisfies it; the list is in get_vocabulary
locationobjectwhere to search: a regionId, or a point with a radius
location.latnumberlatitude of the search centre, paired with lng
location.lngnumberlongitude of the search centre
location.radiusMetersintegerhow far around the point to look
location.regionIdstringthe region to search in, from list_regions or resolve_key
menuOptionsobjectwhat the menu must carry
menuOptions.fishDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
menuOptions.glutenFreeDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
menuOptions.halalDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
menuOptions.lactoseFreeDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
menuOptions.meatDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
menuOptions.veganDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
menuOptions.vegetarianDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
nutritionobjectwhat the venue is as a whole
nutrition.veganRestaurantsbooleantrue narrows to venues carrying it; omit it to not narrow on it
nutrition.vegetarianRestaurantsbooleantrue narrows to venues carrying it; omit it to not narrow on it
openingobjectwhen the venue is open
opening.daytimestringthe service to be open for: lunch or dinner
opening.openOnarray<integer>weekdays it must be open on, Sunday is 0
reservationobjecthow it can be booked
reservation.hasWidgetbooleantrue narrows to venues carrying it; omit it to not narrow on it
reservation.liveAvailabilitybooleantrue narrows to venues carrying it; omit it to not narrow on it

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Count restaurants"
  },
  "description": "How many venues a facet set matches, with no rows. Call this before filter_restaurants when exploring a filter space: it answers the same question without the documents.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "drinkOptions": {
        "additionalProperties": false,
        "description": "what the drinks list must carry",
        "properties": {
          "beerSelection": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "cocktailSelection": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "natureWineSelection": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "wineSelection": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "kitchen": {
        "additionalProperties": false,
        "description": "the kitchen it cooks",
        "properties": {
          "cuisine": {
            "description": "cuisine slugs, any one of which satisfies it; the list is in get_vocabulary",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "location": {
        "additionalProperties": false,
        "description": "where to search: a regionId, or a point with a radius",
        "properties": {
          "lat": {
            "description": "latitude of the search centre, paired with lng",
            "type": "number"
          },
          "lng": {
            "description": "longitude of the search centre",
            "type": "number"
          },
          "radiusMeters": {
            "description": "how far around the point to look",
            "type": "integer"
          },
          "regionId": {
            "description": "the region to search in, from list_regions or resolve_key",
            "type": "string"
          }
        },
        "type": "object"
      },
      "menuOptions": {
        "additionalProperties": false,
        "description": "what the menu must carry",
        "properties": {
          "fishDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "glutenFreeDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "halalDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "lactoseFreeDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "meatDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "veganDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "vegetarianDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "nutrition": {
        "additionalProperties": false,
        "description": "what the venue is as a whole",
        "properties": {
          "veganRestaurants": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "vegetarianRestaurants": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "opening": {
        "additionalProperties": false,
        "description": "when the venue is open",
        "properties": {
          "daytime": {
            "description": "the service to be open for: lunch or dinner",
            "type": "string"
          },
          "openOn": {
            "description": "weekdays it must be open on, Sunday is 0",
            "items": {
              "type": "integer"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "reservation": {
        "additionalProperties": false,
        "description": "how it can be booked",
        "properties": {
          "hasWidget": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "liveAvailability": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          }
        },
        "type": "object"
      }
    },
    "required": [],
    "type": "object"
  },
  "name": "count_restaurants",
  "title": "Count restaurants"
}

🟢 filter_restaurants read Search venues by facet: where, when open, what kitchen, what the menu and the drinks list carry, and how it can be booked. Every facet narrows the result to the venues carrying it, so pass only what the guest asked for. Descriptor and cuisine values come from get_vocabulary — an invented one is refused rather than ignored. Ranked by popularity; no taste vector is applied.

Filter restaurants

Search venues by facet: where, when open, what kitchen, what the menu and the drinks list carry, and how it can be booked. Every facet narrows the result to the venues carrying it, so pass only what the guest asked for. Descriptor and cuisine values come from get_vocabulary — an invented one is refused rather than ignored. Ranked by popularity; no taste vector is applied.

ParameterTypeDescription
drinkOptionsobjectwhat the drinks list must carry
drinkOptions.beerSelectionbooleantrue narrows to venues carrying it; omit it to not narrow on it
drinkOptions.cocktailSelectionbooleantrue narrows to venues carrying it; omit it to not narrow on it
drinkOptions.natureWineSelectionbooleantrue narrows to venues carrying it; omit it to not narrow on it
drinkOptions.wineSelectionbooleantrue narrows to venues carrying it; omit it to not narrow on it
kitchenobjectthe kitchen it cooks
kitchen.cuisinearray<string>cuisine slugs, any one of which satisfies it; the list is in get_vocabulary
limitintegerrows to return, at most 50
locationobjectwhere to search: a regionId, or a point with a radius
location.latnumberlatitude of the search centre, paired with lng
location.lngnumberlongitude of the search centre
location.radiusMetersintegerhow far around the point to look
location.regionIdstringthe region to search in, from list_regions or resolve_key
menuOptionsobjectwhat the menu must carry
menuOptions.fishDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
menuOptions.glutenFreeDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
menuOptions.halalDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
menuOptions.lactoseFreeDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
menuOptions.meatDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
menuOptions.veganDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
menuOptions.vegetarianDishesbooleantrue narrows to venues carrying it; omit it to not narrow on it
nutritionobjectwhat the venue is as a whole
nutrition.veganRestaurantsbooleantrue narrows to venues carrying it; omit it to not narrow on it
nutrition.vegetarianRestaurantsbooleantrue narrows to venues carrying it; omit it to not narrow on it
offsetintegerrows to skip; with totalCount in the result this pages through them
openingobjectwhen the venue is open
opening.daytimestringthe service to be open for: lunch or dinner
opening.openOnarray<integer>weekdays it must be open on, Sunday is 0
reservationobjecthow it can be booked
reservation.hasWidgetbooleantrue narrows to venues carrying it; omit it to not narrow on it
reservation.liveAvailabilitybooleantrue narrows to venues carrying it; omit it to not narrow on it

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Filter restaurants"
  },
  "description": "Search venues by facet: where, when open, what kitchen, what the menu and the drinks list carry, and how it can be booked. Every facet narrows the result to the venues carrying it, so pass only what the guest asked for. Descriptor and cuisine values come from get_vocabulary — an invented one is refused rather than ignored. Ranked by popularity; no taste vector is applied.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "drinkOptions": {
        "additionalProperties": false,
        "description": "what the drinks list must carry",
        "properties": {
          "beerSelection": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "cocktailSelection": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "natureWineSelection": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "wineSelection": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "kitchen": {
        "additionalProperties": false,
        "description": "the kitchen it cooks",
        "properties": {
          "cuisine": {
            "description": "cuisine slugs, any one of which satisfies it; the list is in get_vocabulary",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "limit": {
        "description": "rows to return, at most 50",
        "type": "integer"
      },
      "location": {
        "additionalProperties": false,
        "description": "where to search: a regionId, or a point with a radius",
        "properties": {
          "lat": {
            "description": "latitude of the search centre, paired with lng",
            "type": "number"
          },
          "lng": {
            "description": "longitude of the search centre",
            "type": "number"
          },
          "radiusMeters": {
            "description": "how far around the point to look",
            "type": "integer"
          },
          "regionId": {
            "description": "the region to search in, from list_regions or resolve_key",
            "type": "string"
          }
        },
        "type": "object"
      },
      "menuOptions": {
        "additionalProperties": false,
        "description": "what the menu must carry",
        "properties": {
          "fishDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "glutenFreeDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "halalDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "lactoseFreeDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "meatDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "veganDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "vegetarianDishes": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "nutrition": {
        "additionalProperties": false,
        "description": "what the venue is as a whole",
        "properties": {
          "veganRestaurants": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "vegetarianRestaurants": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "offset": {
        "description": "rows to skip; with totalCount in the result this pages through them",
        "type": "integer"
      },
      "opening": {
        "additionalProperties": false,
        "description": "when the venue is open",
        "properties": {
          "daytime": {
            "description": "the service to be open for: lunch or dinner",
            "type": "string"
          },
          "openOn": {
            "description": "weekdays it must be open on, Sunday is 0",
            "items": {
              "type": "integer"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "reservation": {
        "additionalProperties": false,
        "description": "how it can be booked",
        "properties": {
          "hasWidget": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          },
          "liveAvailability": {
            "description": "true narrows to venues carrying it; omit it to not narrow on it",
            "type": "boolean"
          }
        },
        "type": "object"
      }
    },
    "required": [],
    "type": "object"
  },
  "name": "filter_restaurants",
  "title": "Filter restaurants"
}

🟢 list_popular_restaurants read The most-liked venues of one region. A region is required: without one this reads every venue we hold.

List popular restaurants

The most-liked venues of one region. A region is required: without one this reads every venue we hold.

ParameterTypeDescription
regionId requiredstringthe region to read, from list_regions
limitintegerrows to return, at most 50
offsetintegerrows to skip; with totalCount in the result this pages through them

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "List popular restaurants"
  },
  "description": "The most-liked venues of one region. A region is required: without one this reads every venue we hold.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "limit": {
        "description": "rows to return, at most 50",
        "type": "integer"
      },
      "offset": {
        "description": "rows to skip; with totalCount in the result this pages through them",
        "type": "integer"
      },
      "regionId": {
        "description": "the region to read, from list_regions",
        "type": "string"
      }
    },
    "required": [
      "regionId"
    ],
    "type": "object"
  },
  "name": "list_popular_restaurants",
  "title": "List popular restaurants"
}

🟡 list_recommended_restaurants read Venues recommended for the signed-in guest, closest in taste first; before anyone signs in they are not personal. `bookableOnly` keeps only venues with a table free, which is a much smaller set and needs a sign-in.

List recommended restaurants

Venues recommended for the signed-in guest, closest in taste first; before anyone signs in they are not personal. `bookableOnly` keeps only venues with a table free, which is a much smaller set and needs a sign-in.

ParameterTypeDescription
bookableOnlybooleankeep only venues with live availability
interDiemintegerwith bookableOnly, how many days ahead a free table may lie
limitintegerrows to return, at most 50
offsetintegerrows to skip; with totalCount in the result this pages through them
regionIdstringthe region to recommend in; the identity's own region when omitted

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "List recommended restaurants"
  },
  "description": "Venues recommended for the signed-in guest, closest in taste first; before anyone signs in they are not personal. \`bookableOnly\` keeps only venues with a table free, which is a much smaller set and needs a sign-in.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "bookableOnly": {
        "description": "keep only venues with live availability",
        "type": "boolean"
      },
      "interDiem": {
        "description": "with bookableOnly, how many days ahead a free table may lie",
        "type": "integer"
      },
      "limit": {
        "description": "rows to return, at most 50",
        "type": "integer"
      },
      "offset": {
        "description": "rows to skip; with totalCount in the result this pages through them",
        "type": "integer"
      },
      "regionId": {
        "description": "the region to recommend in; the identity's own region when omitted",
        "type": "string"
      }
    },
    "required": [],
    "type": "object"
  },
  "name": "list_recommended_restaurants",
  "title": "List recommended restaurants"
}

🟢 list_similar_restaurants read Venues close in taste to one you already hold a key for, nearest first. `sameCategory` keeps them inside the same kitchen family and is on unless you turn it off.

List similar restaurants

Venues close in taste to one you already hold a key for, nearest first. `sameCategory` keeps them inside the same kitchen family and is on unless you turn it off.

ParameterTypeDescription
restaurantKey requiredstringthe venue to find neighbours of
limitintegerrows to return, at most 50
offsetintegerrows to skip; with totalCount in the result this pages through them
sameCategorybooleankeep to the same kitchen family; true when omitted

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "List similar restaurants"
  },
  "description": "Venues close in taste to one you already hold a key for, nearest first. \`sameCategory\` keeps them inside the same kitchen family and is on unless you turn it off.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "limit": {
        "description": "rows to return, at most 50",
        "type": "integer"
      },
      "offset": {
        "description": "rows to skip; with totalCount in the result this pages through them",
        "type": "integer"
      },
      "restaurantKey": {
        "description": "the venue to find neighbours of",
        "type": "string"
      },
      "sameCategory": {
        "description": "keep to the same kitchen family; true when omitted",
        "type": "boolean"
      }
    },
    "required": [
      "restaurantKey"
    ],
    "type": "object"
  },
  "name": "list_similar_restaurants",
  "title": "List similar restaurants"
}

🟢 search_dishes read Find the venues that serve a named dish. Search the dish as the guest said it, in their words and their order — the wording of a dish is part of its identity, so do not rephrase, translate or shorten it. Longer words survive a small spelling slip; very short ones must be exact. Every hit quotes the dish as the menu prints it, and `exact` is true only where the name matched word for word. This knows nothing of opening hours — use filter_restaurants for that. Menu coverage is partial: an empty result means no menu we hold names that dish, never that nobody cooks it.

Search dishes

Find the venues that serve a named dish. Search the dish as the guest said it, in their words and their order — the wording of a dish is part of its identity, so do not rephrase, translate or shorten it. Longer words survive a small spelling slip; very short ones must be exact. Every hit quotes the dish as the menu prints it, and `exact` is true only where the name matched word for word. This knows nothing of opening hours — use filter_restaurants for that. Menu coverage is partial: an empty result means no menu we hold names that dish, never that nobody cooks it.

ParameterTypeDescription
q requiredstringthe dish as the guest named it
latnumberlatitude to search around, paired with lng
limitintegerrows to return, at most 50
lngnumberlongitude to search around
offsetintegerrows to skip; with totalCount in the result this pages through them
radiusMetersintegerhow far around the point to look
regionIdstringbound the search to one region

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Search dishes"
  },
  "description": "Find the venues that serve a named dish. Search the dish as the guest said it, in their words and their order — the wording of a dish is part of its identity, so do not rephrase, translate or shorten it. Longer words survive a small spelling slip; very short ones must be exact. Every hit quotes the dish as the menu prints it, and \`exact\` is true only where the name matched word for word. This knows nothing of opening hours — use filter_restaurants for that. Menu coverage is partial: an empty result means no menu we hold names that dish, never that nobody cooks it.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "lat": {
        "description": "latitude to search around, paired with lng",
        "type": "number"
      },
      "limit": {
        "description": "rows to return, at most 50",
        "type": "integer"
      },
      "lng": {
        "description": "longitude to search around",
        "type": "number"
      },
      "offset": {
        "description": "rows to skip; with totalCount in the result this pages through them",
        "type": "integer"
      },
      "q": {
        "description": "the dish as the guest named it",
        "type": "string"
      },
      "radiusMeters": {
        "description": "how far around the point to look",
        "type": "integer"
      },
      "regionId": {
        "description": "bound the search to one region",
        "type": "string"
      }
    },
    "required": [
      "q"
    ],
    "type": "object"
  },
  "name": "search_dishes",
  "title": "Search dishes"
}

🟢 search_restaurants read Find venues by name or by what they are called, in the guest's own words. Three characters at least. Bound it to a region when you know one. Use filter_restaurants when the guest described a kind of place rather than named one.

Search restaurants

Find venues by name or by what they are called, in the guest's own words. Three characters at least. Bound it to a region when you know one. Use filter_restaurants when the guest described a kind of place rather than named one.

ParameterTypeDescription
text requiredstringwhat to search for, three characters or more
limitintegerrows to return, at most 50
offsetintegerrows to skip; with totalCount in the result this pages through them
regionIdstringbound the search to one region; omitted it searches every region we cover

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Search restaurants"
  },
  "description": "Find venues by name or by what they are called, in the guest's own words. Three characters at least. Bound it to a region when you know one. Use filter_restaurants when the guest described a kind of place rather than named one.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "limit": {
        "description": "rows to return, at most 50",
        "type": "integer"
      },
      "offset": {
        "description": "rows to skip; with totalCount in the result this pages through them",
        "type": "integer"
      },
      "regionId": {
        "description": "bound the search to one region; omitted it searches every region we cover",
        "type": "string"
      },
      "text": {
        "description": "what to search for, three characters or more",
        "type": "string"
      }
    },
    "required": [
      "text"
    ],
    "type": "object"
  },
  "name": "search_restaurants",
  "title": "Search restaurants"
}

PLACE

🟢 list_regions read The regions TasteMatch covers. Each carries the regionId every region-scoped tool takes, and the IANA timezone its venues' opening hours and slot times are written on. Pass a point to get them nearest first. A place not in any of these regions has no venues we hold.

List regions

The regions TasteMatch covers. Each carries the regionId every region-scoped tool takes, and the IANA timezone its venues' opening hours and slot times are written on. Pass a point to get them nearest first. A place not in any of these regions has no venues we hold.

ParameterTypeDescription
latnumberlatitude to sort by distance from, paired with lng
limitintegerrows to return, at most 50
lngnumberlongitude to sort by distance from
offsetintegerrows to skip; with totalCount in the result this pages through them

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "List regions"
  },
  "description": "The regions TasteMatch covers. Each carries the regionId every region-scoped tool takes, and the IANA timezone its venues' opening hours and slot times are written on. Pass a point to get them nearest first. A place not in any of these regions has no venues we hold.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "lat": {
        "description": "latitude to sort by distance from, paired with lng",
        "type": "number"
      },
      "limit": {
        "description": "rows to return, at most 50",
        "type": "integer"
      },
      "lng": {
        "description": "longitude to sort by distance from",
        "type": "number"
      },
      "offset": {
        "description": "rows to skip; with totalCount in the result this pages through them",
        "type": "integer"
      }
    },
    "required": [],
    "type": "object"
  },
  "name": "list_regions",
  "title": "List regions"
}

🟢 search_places read Match a town, district or quarter the guest named to the region that contains it. An empty result means the place is outside every region we cover, not that the name was wrong.

Search places

Match a town, district or quarter the guest named to the region that contains it. An empty result means the place is outside every region we cover, not that the name was wrong.

ParameterTypeDescription
q requiredstringthe place as the guest named it
countryCodestringISO 3166-1 alpha-2 code to restrict the match to
limitintegerrows to return, at most 50
offsetintegerrows to skip; with totalCount in the result this pages through them

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Search places"
  },
  "description": "Match a town, district or quarter the guest named to the region that contains it. An empty result means the place is outside every region we cover, not that the name was wrong.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "countryCode": {
        "description": "ISO 3166-1 alpha-2 code to restrict the match to",
        "type": "string"
      },
      "limit": {
        "description": "rows to return, at most 50",
        "type": "integer"
      },
      "offset": {
        "description": "rows to skip; with totalCount in the result this pages through them",
        "type": "integer"
      },
      "q": {
        "description": "the place as the guest named it",
        "type": "string"
      }
    },
    "required": [
      "q"
    ],
    "type": "object"
  },
  "name": "search_places",
  "title": "Search places"
}

RESTAURANT

🟢 get_restaurant read Read one venue. The default projection is lean — name, keys, region, address, descriptors, how it can be booked and its opening summary. The heavy parts arrive only when you name them in `fields`: ContactInformation, MenuCards, MenuCardsV2, labelVector, coverPictures, socialScore, matchInfo, tmType, eventId, businessPro, likesByUser, likesByFollowees, likesUserAvatars, likesFolloweeAvatars. An unprojected document can be larger than the rest of your task.

Get restaurant

Read one venue. The default projection is lean — name, keys, region, address, descriptors, how it can be booked and its opening summary. The heavy parts arrive only when you name them in `fields`: ContactInformation, MenuCards, MenuCardsV2, labelVector, coverPictures, socialScore, matchInfo, tmType, eventId, businessPro, likesByUser, likesByFollowees, likesUserAvatars, likesFolloweeAvatars. An unprojected document can be larger than the rest of your task.

ParameterTypeDescription
restaurantKey requiredstringthe venue's key
accessTypestringwhen the guest asked to open this venue, how they reached it — one of filtered, searched, recommended, similar, popular, spotlight. The open is then counted as theirs; leave it out when you are only checking a venue for yourself.
fieldsarray<string>the fields to return; the default projection is lean, and keys are always included

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Get restaurant"
  },
  "description": "Read one venue. The default projection is lean — name, keys, region, address, descriptors, how it can be booked and its opening summary. The heavy parts arrive only when you name them in \`fields\`: ContactInformation, MenuCards, MenuCardsV2, labelVector, coverPictures, socialScore, matchInfo, tmType, eventId, businessPro, likesByUser, likesByFollowees, likesUserAvatars, likesFolloweeAvatars. An unprojected document can be larger than the rest of your task.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "accessType": {
        "description": "when the guest asked to open this venue, how they reached it — one of filtered, searched, recommended, similar, popular, spotlight. The open is then counted as theirs; leave it out when you are only checking a venue for yourself.",
        "type": "string"
      },
      "fields": {
        "description": "the fields to return; the default projection is lean, and keys are always included",
        "items": {
          "type": "string"
        },
        "type": "array"
      },
      "restaurantKey": {
        "description": "the venue's key",
        "type": "string"
      }
    },
    "required": [
      "restaurantKey"
    ],
    "type": "object"
  },
  "name": "get_restaurant",
  "title": "Get restaurant"
}

🔴 like_restaurant write Record that the acting identity likes this venue. Liking is what makes the recommendations that follow better, and it is the guest's statement, not yours — like what they said they liked.

Like restaurant

Record that the acting identity likes this venue. Liking is what makes the recommendations that follow better, and it is the guest's statement, not yours — like what they said they liked.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
restaurantKey requiredstringthe venue's key

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Like restaurant"
  },
  "description": "Record that the acting identity likes this venue. Liking is what makes the recommendations that follow better, and it is the guest's statement, not yours — like what they said they liked.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "restaurantKey": {
        "description": "the venue's key",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey",
      "restaurantKey"
    ],
    "type": "object"
  },
  "name": "like_restaurant",
  "title": "Like restaurant"
}

🔴 submit_restaurant_impressions write Tell us which venues the identity actually saw, and which of them it acted on. One batch per turn, with a sessionId of your own that stays the same for the whole conversation. Report what happened, never what you intend: these are the signals the recommender learns from.

Submit restaurant impressions

Tell us which venues the identity actually saw, and which of them it acted on. One batch per turn, with a sessionId of your own that stays the same for the whole conversation. Report what happened, never what you intend: these are the signals the recommender learns from.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
impressions requiredarray<object>what was shown or acted on
impressions[].accessType requiredstringone of filtered, searched, recommended, similar, popular, spotlight
impressions[].restaurantKey requiredstring
sessionId requiredstringa UUID of your own, the same for every batch in one conversation

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Submit restaurant impressions"
  },
  "description": "Tell us which venues the identity actually saw, and which of them it acted on. One batch per turn, with a sessionId of your own that stays the same for the whole conversation. Report what happened, never what you intend: these are the signals the recommender learns from.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "impressions": {
        "description": "what was shown or acted on",
        "items": {
          "additionalProperties": false,
          "properties": {
            "accessType": {
              "description": "one of filtered, searched, recommended, similar, popular, spotlight",
              "type": "string"
            },
            "restaurantKey": {
              "type": "string"
            }
          },
          "required": [
            "accessType",
            "restaurantKey"
          ],
          "type": "object"
        },
        "type": "array"
      },
      "sessionId": {
        "description": "a UUID of your own, the same for every batch in one conversation",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey",
      "impressions",
      "sessionId"
    ],
    "type": "object"
  },
  "name": "submit_restaurant_impressions",
  "title": "Submit restaurant impressions"
}

🔴 unlike_restaurant write Take back a like. The venue stays in the catalogue; only the identity's opinion of it is removed.

Unlike restaurant

Take back a like. The venue stays in the catalogue; only the identity's opinion of it is removed.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
restaurantKey requiredstringthe venue's key

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Unlike restaurant"
  },
  "description": "Take back a like. The venue stays in the catalogue; only the identity's opinion of it is removed.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "restaurantKey": {
        "description": "the venue's key",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey",
      "restaurantKey"
    ],
    "type": "object"
  },
  "name": "unlike_restaurant",
  "title": "Unlike restaurant"
}

AVAILABILITY

🟢 get_reservation_info read How this venue takes reservations. `mode` is instant when tables are confirmed live, request when someone at the venue has to accept, and the tool refuses when the venue takes none at all. Read this first: it decides whether you call create_instant_reservation or create_reservation_request. `maxPeople` is the largest party we can place anywhere. This reads only — it books nothing and records nothing.

Get reservation info

How this venue takes reservations. `mode` is instant when tables are confirmed live, request when someone at the venue has to accept, and the tool refuses when the venue takes none at all. Read this first: it decides whether you call create_instant_reservation or create_reservation_request. `maxPeople` is the largest party we can place anywhere. This reads only — it books nothing and records nothing.

ParameterTypeDescription
restaurantKey requiredstringthe venue's key

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Get reservation info"
  },
  "description": "How this venue takes reservations. \`mode\` is instant when tables are confirmed live, request when someone at the venue has to accept, and the tool refuses when the venue takes none at all. Read this first: it decides whether you call create_instant_reservation or create_reservation_request. \`maxPeople\` is the largest party we can place anywhere. This reads only — it books nothing and records nothing.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "restaurantKey": {
        "description": "the venue's key",
        "type": "string"
      }
    },
    "required": [
      "restaurantKey"
    ],
    "type": "object"
  },
  "name": "get_reservation_info",
  "title": "Get reservation info"
}

🟢 list_availability_slots read The tables free at one venue on one day. Times are the venue's own wall clock, and they sit on no fixed grid — book a time you read here rather than a round number you chose. A request-mode venue answers in `windows` instead: the spans it will consider a request inside. Both empty means shut that day, or past the booking horizon.

List availability slots

The tables free at one venue on one day. Times are the venue's own wall clock, and they sit on no fixed grid — book a time you read here rather than a round number you chose. A request-mode venue answers in `windows` instead: the spans it will consider a request inside. Both empty means shut that day, or past the booking horizon.

ParameterTypeDescription
date requiredstringthe day to read, RFC3339 with the region's UTC offset
restaurantKey requiredstringthe venue's key
paxintegerparty size, to drop slots too small for it

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "List availability slots"
  },
  "description": "The tables free at one venue on one day. Times are the venue's own wall clock, and they sit on no fixed grid — book a time you read here rather than a round number you chose. A request-mode venue answers in \`windows\` instead: the spans it will consider a request inside. Both empty means shut that day, or past the booking horizon.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "date": {
        "description": "the day to read, RFC3339 with the region's UTC offset",
        "type": "string"
      },
      "pax": {
        "description": "party size, to drop slots too small for it",
        "type": "integer"
      },
      "restaurantKey": {
        "description": "the venue's key",
        "type": "string"
      }
    },
    "required": [
      "date",
      "restaurantKey"
    ],
    "type": "object"
  },
  "name": "list_availability_slots",
  "title": "List availability slots"
}

RESERVATION

🔴 cancel_reservation destructive Cancel a reservation the identity owns. This cannot be undone and the table is given up. Read the reservation first, say the venue and the time back to the guest, wait for them, and then echo both here: `confirmRestaurantName` and `confirmDateTime` must match the reservation on file or the call is refused. Never cancel on a key alone, however sure you are of it.

Cancel reservation

Cancel a reservation the identity owns. This cannot be undone and the table is given up. Read the reservation first, say the venue and the time back to the guest, wait for them, and then echo both here: `confirmRestaurantName` and `confirmDateTime` must match the reservation on file or the call is refused. Never cancel on a key alone, however sure you are of it.

ParameterTypeDescription
confirmDateTime requiredstringthe reservation's time as you said it to the guest, RFC3339
confirmRestaurantName requiredstringthe venue's name as you said it to the guest
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
reservationKey requiredstringthe reservation to cancel, from the owned set of list_reservations

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": true,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Cancel reservation"
  },
  "description": "Cancel a reservation the identity owns. This cannot be undone and the table is given up. Read the reservation first, say the venue and the time back to the guest, wait for them, and then echo both here: \`confirmRestaurantName\` and \`confirmDateTime\` must match the reservation on file or the call is refused. Never cancel on a key alone, however sure you are of it.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "confirmDateTime": {
        "description": "the reservation's time as you said it to the guest, RFC3339",
        "type": "string"
      },
      "confirmRestaurantName": {
        "description": "the venue's name as you said it to the guest",
        "type": "string"
      },
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "reservationKey": {
        "description": "the reservation to cancel, from the owned set of list_reservations",
        "type": "string"
      }
    },
    "required": [
      "confirmDateTime",
      "confirmRestaurantName",
      "idempotencyKey",
      "reservationKey"
    ],
    "type": "object"
  },
  "name": "cancel_reservation",
  "title": "Cancel reservation"
}

🔴 create_instant_reservation write Take a table that is free now. This is for instant venues and the table is confirmed when it returns. Book a `dateTime` you read from list_availability_slots — the venue's slots sit on no grid, so a round number is usually not one of them. Leave `approxMinutes` at 0 unless the guest said they are flexible: a non-zero value lets the venue book a nearby time instead, and the answer says so in `adjusted` and `bookedDate`. The booking runs on the stored identity, which needs both an email and a phone for an instant venue.

Create instant reservation

Take a table that is free now. This is for instant venues and the table is confirmed when it returns. Book a `dateTime` you read from list_availability_slots — the venue's slots sit on no grid, so a round number is usually not one of them. Leave `approxMinutes` at 0 unless the guest said they are flexible: a non-zero value lets the venue book a nearby time instead, and the answer says so in `adjusted` and `bookedDate`. The booking runs on the stored identity, which needs both an email and a phone for an instant venue.

ParameterTypeDescription
dateTime requiredstringthe slot to take, RFC3339 with the region's UTC offset, as read from list_availability_slots
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
pax requiredintegerparty size
restaurantKey requiredstringthe venue's key
approxMinutesintegerhow far from dateTime the venue may book instead; 0 means this time or nothing
areaIdstringthe area to seat in, from the slot you chose; it narrows the search and never moves the booking
commentstringa note for the venue, in the guest's words

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Create instant reservation"
  },
  "description": "Take a table that is free now. This is for instant venues and the table is confirmed when it returns. Book a \`dateTime\` you read from list_availability_slots — the venue's slots sit on no grid, so a round number is usually not one of them. Leave \`approxMinutes\` at 0 unless the guest said they are flexible: a non-zero value lets the venue book a nearby time instead, and the answer says so in \`adjusted\` and \`bookedDate\`. The booking runs on the stored identity, which needs both an email and a phone for an instant venue.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "approxMinutes": {
        "description": "how far from dateTime the venue may book instead; 0 means this time or nothing",
        "type": "integer"
      },
      "areaId": {
        "description": "the area to seat in, from the slot you chose; it narrows the search and never moves the booking",
        "type": "string"
      },
      "comment": {
        "description": "a note for the venue, in the guest's words",
        "type": "string"
      },
      "dateTime": {
        "description": "the slot to take, RFC3339 with the region's UTC offset, as read from list_availability_slots",
        "type": "string"
      },
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "pax": {
        "description": "party size",
        "type": "integer"
      },
      "restaurantKey": {
        "description": "the venue's key",
        "type": "string"
      }
    },
    "required": [
      "dateTime",
      "idempotencyKey",
      "pax",
      "restaurantKey"
    ],
    "type": "object"
  },
  "name": "create_instant_reservation",
  "title": "Create instant reservation"
}

🔴 create_reservation_offer write Open a booking at a venue that books through its own widget. This writes: it mints a draft attributed to the acting identity and a single-use `widgetUrl` for the guest to finish in. Hand the URL to the guest, then poll get_reservation_status on the `reservationKey` it returns. Call it once per booking attempt — a second call mints a second draft. A venue that books natively needs no offer: use create_instant_reservation or create_reservation_request instead.

Create reservation offer

Open a booking at a venue that books through its own widget. This writes: it mints a draft attributed to the acting identity and a single-use `widgetUrl` for the guest to finish in. Hand the URL to the guest, then poll get_reservation_status on the `reservationKey` it returns. Call it once per booking attempt — a second call mints a second draft. A venue that books natively needs no offer: use create_instant_reservation or create_reservation_request instead.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
restaurantKey requiredstringthe venue's key

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Create reservation offer"
  },
  "description": "Open a booking at a venue that books through its own widget. This writes: it mints a draft attributed to the acting identity and a single-use \`widgetUrl\` for the guest to finish in. Hand the URL to the guest, then poll get_reservation_status on the \`reservationKey\` it returns. Call it once per booking attempt — a second call mints a second draft. A venue that books natively needs no offer: use create_instant_reservation or create_reservation_request instead.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "restaurantKey": {
        "description": "the venue's key",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey",
      "restaurantKey"
    ],
    "type": "object"
  },
  "name": "create_reservation_offer",
  "title": "Create reservation offer"
}

🔴 create_reservation_request write Ask a venue for a table. This is for request-mode venues: the reservation comes back pending and someone at the venue accepts or declines it, so tell the guest it is not yet a table. The time must fall inside one of the windows list_availability_slots reported. The booking runs on the stored identity — its name and contact are read from the record, not from this call.

Create reservation request

Ask a venue for a table. This is for request-mode venues: the reservation comes back pending and someone at the venue accepts or declines it, so tell the guest it is not yet a table. The time must fall inside one of the windows list_availability_slots reported. The booking runs on the stored identity — its name and contact are read from the record, not from this call.

ParameterTypeDescription
dateTime requiredstringthe time asked for, RFC3339 with the region's UTC offset
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
pax requiredintegerparty size
restaurantKey requiredstringthe venue's key
commentstringa note for the venue, in the guest's words

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Create reservation request"
  },
  "description": "Ask a venue for a table. This is for request-mode venues: the reservation comes back pending and someone at the venue accepts or declines it, so tell the guest it is not yet a table. The time must fall inside one of the windows list_availability_slots reported. The booking runs on the stored identity — its name and contact are read from the record, not from this call.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "comment": {
        "description": "a note for the venue, in the guest's words",
        "type": "string"
      },
      "dateTime": {
        "description": "the time asked for, RFC3339 with the region's UTC offset",
        "type": "string"
      },
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "pax": {
        "description": "party size",
        "type": "integer"
      },
      "restaurantKey": {
        "description": "the venue's key",
        "type": "string"
      }
    },
    "required": [
      "dateTime",
      "idempotencyKey",
      "pax",
      "restaurantKey"
    ],
    "type": "object"
  },
  "name": "create_reservation_request",
  "title": "Create reservation request"
}

🔴 get_reservation_status read Where one reservation of the acting identity stands. Poll this after an offer: a widget booking becomes real only once the venue confirms it, and the status is how that arrives.

Get reservation status

Where one reservation of the acting identity stands. Poll this after an offer: a widget booking becomes real only once the venue confirms it, and the status is how that arrives.

ParameterTypeDescription
reservationKey requiredstringthe reservation's key, from list_reservations

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Get reservation status"
  },
  "description": "Where one reservation of the acting identity stands. Poll this after an offer: a widget booking becomes real only once the venue confirms it, and the status is how that arrives.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "reservationKey": {
        "description": "the reservation's key, from list_reservations",
        "type": "string"
      }
    },
    "required": [
      "reservationKey"
    ],
    "type": "object"
  },
  "name": "get_reservation_status",
  "title": "Get reservation status"
}

🔴 list_reservation_slots read Where an existing reservation could move to. This is a different question from list_availability_slots: it is scoped to the reservation and to what the venue will let it become. Only an accepted reservation at a venue with live availability can move.

List reservation slots

Where an existing reservation could move to. This is a different question from list_availability_slots: it is scoped to the reservation and to what the venue will let it become. Only an accepted reservation at a venue with live availability can move.

ParameterTypeDescription
reservationKey requiredstringthe reservation to move, from list_reservations
fromDatestringthe first day to look at, RFC3339; the reservation's own day when omitted

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "List reservation slots"
  },
  "description": "Where an existing reservation could move to. This is a different question from list_availability_slots: it is scoped to the reservation and to what the venue will let it become. Only an accepted reservation at a venue with live availability can move.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "fromDate": {
        "description": "the first day to look at, RFC3339; the reservation's own day when omitted",
        "type": "string"
      },
      "reservationKey": {
        "description": "the reservation to move, from list_reservations",
        "type": "string"
      }
    },
    "required": [
      "reservationKey"
    ],
    "type": "object"
  },
  "name": "list_reservation_slots",
  "title": "List reservation slots"
}

🔴 list_reservations read Every reservation the acting identity holds. `owned` is actionable — those keys are the ones the write tools take. `foundByEmail` was reassigned to another owner: it is shown so you can speak about it, and every write on it is refused.

List reservations

Every reservation the acting identity holds. `owned` is actionable — those keys are the ones the write tools take. `foundByEmail` was reassigned to another owner: it is shown so you can speak about it, and every write on it is refused.

No parameters.

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "List reservations"
  },
  "description": "Every reservation the acting identity holds. \`owned\` is actionable — those keys are the ones the write tools take. \`foundByEmail\` was reassigned to another owner: it is shown so you can speak about it, and every write on it is refused.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {},
    "required": [],
    "type": "object"
  },
  "name": "list_reservations",
  "title": "List reservations"
}

🔴 update_reservation write Move a reservation the identity owns, or change its party size. Name only what changes. A new time must be one list_reservation_slots offered for that reservation.

Update reservation

Move a reservation the identity owns, or change its party size. Name only what changes. A new time must be one list_reservation_slots offered for that reservation.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
reservationKey requiredstringthe reservation to change, from the owned set of list_reservations
dateTimestringthe new time, RFC3339 with the region's UTC offset
paxintegerthe new party size

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Update reservation"
  },
  "description": "Move a reservation the identity owns, or change its party size. Name only what changes. A new time must be one list_reservation_slots offered for that reservation.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "dateTime": {
        "description": "the new time, RFC3339 with the region's UTC offset",
        "type": "string"
      },
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "pax": {
        "description": "the new party size",
        "type": "integer"
      },
      "reservationKey": {
        "description": "the reservation to change, from the owned set of list_reservations",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey",
      "reservationKey"
    ],
    "type": "object"
  },
  "name": "update_reservation",
  "title": "Update reservation"
}

IDENTITY

🔴 get_identity read The identity you are acting for. Read it before asking the guest for anything: a value already on file is never replaced, and asking again for what we hold reads as not listening.

Get identity

The identity you are acting for. Read it before asking the guest for anything: a value already on file is never replaced, and asking again for what we hold reads as not listening.

No parameters.

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Get identity"
  },
  "description": "The identity you are acting for. Read it before asking the guest for anything: a value already on file is never replaced, and asking again for what we hold reads as not listening.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {},
    "required": [],
    "type": "object"
  },
  "name": "get_identity",
  "title": "Get identity"
}

🟢 get_session read What this connection reaches: the journeys open to it, and the signed-in person you act for with their rung — `acting` is absent until someone signs in. Call it first when unsure whether anyone is signed in, and read `climbWith` for the tool that collects whatever the current rung is missing.

Get session

What this connection reaches: the journeys open to it, and the signed-in person you act for with their rung — `acting` is absent until someone signs in. Call it first when unsure whether anyone is signed in, and read `climbWith` for the tool that collects whatever the current rung is missing.

No parameters.

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Get session"
  },
  "description": "What this connection reaches: the journeys open to it, and the signed-in person you act for with their rung — \`acting\` is absent until someone signs in. Call it first when unsure whether anyone is signed in, and read \`climbWith\` for the tool that collects whatever the current rung is missing.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {},
    "required": [],
    "type": "object"
  },
  "name": "get_session",
  "title": "Get session"
}

🔴 promote_identity write Climb to the rung that can reserve, by supplying what the identity is missing: a first and last name, one contact channel, and accepted Terms. Only send what the guest told you in this conversation. An instant venue needs both an email and a phone, so collect both when the guest wants a confirmed table.

Promote identity

Climb to the rung that can reserve, by supplying what the identity is missing: a first and last name, one contact channel, and accepted Terms. Only send what the guest told you in this conversation. An instant venue needs both an email and a phone, so collect both when the guest wants a confirmed table.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
acceptTermsbooleantrue when the guest accepts the Terms at https://www.tastematch.io/agb
emailstringcontact email
firstNamestringthe guest's first name
lastNamestringthe guest's last name
phonestringcontact phone in international format

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Promote identity"
  },
  "description": "Climb to the rung that can reserve, by supplying what the identity is missing: a first and last name, one contact channel, and accepted Terms. Only send what the guest told you in this conversation. An instant venue needs both an email and a phone, so collect both when the guest wants a confirmed table.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "acceptTerms": {
        "description": "true when the guest accepts the Terms at https://www.tastematch.io/agb",
        "type": "boolean"
      },
      "email": {
        "description": "contact email",
        "type": "string"
      },
      "firstName": {
        "description": "the guest's first name",
        "type": "string"
      },
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "lastName": {
        "description": "the guest's last name",
        "type": "string"
      },
      "phone": {
        "description": "contact phone in international format",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey"
    ],
    "type": "object"
  },
  "name": "promote_identity",
  "title": "Promote identity"
}

🔴 update_identity write Correct or complete the identity. A blank field is filled and a wrong one is corrected, but a channel the guest has validated cannot be replaced from here. Send only what changed.

Update identity

Correct or complete the identity. A blank field is filled and a wrong one is corrected, but a channel the guest has validated cannot be replaced from here. Send only what changed.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
acceptTermsbooleantrue when the guest accepts the Terms at https://www.tastematch.io/agb
emailstringcontact email
firstNamestringthe guest's first name
lastNamestringthe guest's last name
phonestringcontact phone in international format

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Update identity"
  },
  "description": "Correct or complete the identity. A blank field is filled and a wrong one is corrected, but a channel the guest has validated cannot be replaced from here. Send only what changed.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "acceptTerms": {
        "description": "true when the guest accepts the Terms at https://www.tastematch.io/agb",
        "type": "boolean"
      },
      "email": {
        "description": "contact email",
        "type": "string"
      },
      "firstName": {
        "description": "the guest's first name",
        "type": "string"
      },
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "lastName": {
        "description": "the guest's last name",
        "type": "string"
      },
      "phone": {
        "description": "contact phone in international format",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey"
    ],
    "type": "object"
  },
  "name": "update_identity",
  "title": "Update identity"
}

TASTE

🔴 get_taste_profile read What this identity's taste is on file as: the descriptors it carries, the confidence stated for each, and the taste type derived from them. Read it before stating taste again — you are correcting a profile, not starting one.

Get taste profile

What this identity's taste is on file as: the descriptors it carries, the confidence stated for each, and the taste type derived from them. Read it before stating taste again — you are correcting a profile, not starting one.

No parameters.

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Get taste profile"
  },
  "description": "What this identity's taste is on file as: the descriptors it carries, the confidence stated for each, and the taste type derived from them. Read it before stating taste again — you are correcting a profile, not starting one.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {},
    "required": [],
    "type": "object"
  },
  "name": "get_taste_profile",
  "title": "Get taste profile"
}

🔴 submit_taste_profile write State the guest's taste as a confidence from 0 to 1 per descriptor, and infer as many as the conversation supports. This replaces what was on file, so send the whole picture rather than a correction. The descriptors are the ones `weights` names, all published by get_vocabulary — any other is refused. Occasions and menu characters are stored with the rest but are venue attributes, so they shape filters rather than the taste vector. Optional: discovery, lists and booking all work without it; it only makes list_recommended_restaurants personal.

Submit taste profile

State the guest's taste as a confidence from 0 to 1 per descriptor, and infer as many as the conversation supports. This replaces what was on file, so send the whole picture rather than a correction. The descriptors are the ones `weights` names, all published by get_vocabulary — any other is refused. Occasions and menu characters are stored with the rest but are venue attributes, so they shape filters rather than the taste vector. Optional: discovery, lists and booking all work without it; it only makes list_recommended_restaurants personal.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
weights requiredmap<string, number>confidence 0 to 1 per descriptor, one of apero, breakfast, brunch, dinner, dishCocktails, dishCraftBeer, dishNatureWine, dishWine, fineDining, late, lunch, menuFish, menuMeat, menuVegan, menuVegetarian, occasionBusiness, occasionCasual, occasionCelebration, occasionChildren, occasionCulture, occasionGroups, occasionImpressive, occasionRomantic, occasionSolo, priceCheap, pricePricey, salty, sweets

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Submit taste profile"
  },
  "description": "State the guest's taste as a confidence from 0 to 1 per descriptor, and infer as many as the conversation supports. This replaces what was on file, so send the whole picture rather than a correction. The descriptors are the ones \`weights\` names, all published by get_vocabulary — any other is refused. Occasions and menu characters are stored with the rest but are venue attributes, so they shape filters rather than the taste vector. Optional: discovery, lists and booking all work without it; it only makes list_recommended_restaurants personal.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "weights": {
        "additionalProperties": {
          "type": "number"
        },
        "description": "confidence 0 to 1 per descriptor, one of apero, breakfast, brunch, dinner, dishCocktails, dishCraftBeer, dishNatureWine, dishWine, fineDining, late, lunch, menuFish, menuMeat, menuVegan, menuVegetarian, occasionBusiness, occasionCasual, occasionCelebration, occasionChildren, occasionCulture, occasionGroups, occasionImpressive, occasionRomantic, occasionSolo, priceCheap, pricePricey, salty, sweets",
        "type": "object"
      }
    },
    "required": [
      "idempotencyKey",
      "weights"
    ],
    "type": "object"
  },
  "name": "submit_taste_profile",
  "title": "Submit taste profile"
}

LISTS

🔴 add_restaurant_to_list write Put a venue on one of the identity's lists. Adding one that is already there changes nothing.

Add restaurant to list

Put a venue on one of the identity's lists. Adding one that is already there changes nothing.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
listKey requiredstringthe list to add to
restaurantKey requiredstringthe venue to add

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Add restaurant to list"
  },
  "description": "Put a venue on one of the identity's lists. Adding one that is already there changes nothing.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "listKey": {
        "description": "the list to add to",
        "type": "string"
      },
      "restaurantKey": {
        "description": "the venue to add",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey",
      "listKey",
      "restaurantKey"
    ],
    "type": "object"
  },
  "name": "add_restaurant_to_list",
  "title": "Add restaurant to list"
}

🔴 create_list write Start a named list for the identity. Name it for what it is for — the guest will see the name again next time, and so will you.

Create list

Start a named list for the identity. Name it for what it is for — the guest will see the name again next time, and so will you.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
title requiredstringwhat the list is for, in the guest's language

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Create list"
  },
  "description": "Start a named list for the identity. Name it for what it is for — the guest will see the name again next time, and so will you.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "title": {
        "description": "what the list is for, in the guest's language",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey",
      "title"
    ],
    "type": "object"
  },
  "name": "create_list",
  "title": "Create list"
}

🔴 delete_list destructive Delete one of the identity's lists and everything on it. Read the list first and tell the guest what will go; this cannot be undone.

Delete list

Delete one of the identity's lists and everything on it. Read the list first and tell the guest what will go; this cannot be undone.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
listKey requiredstringthe list to delete

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": true,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Delete list"
  },
  "description": "Delete one of the identity's lists and everything on it. Read the list first and tell the guest what will go; this cannot be undone.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "listKey": {
        "description": "the list to delete",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey",
      "listKey"
    ],
    "type": "object"
  },
  "name": "delete_list",
  "title": "Delete list"
}

🔴 get_list read Read one of the acting identity's lists in full, with every venue on it. Another identity's list is not readable.

Get list

Read one of the acting identity's lists in full, with every venue on it. Another identity's list is not readable.

ParameterTypeDescription
listKey requiredstringthe list's key, from list_lists

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Get list"
  },
  "description": "Read one of the acting identity's lists in full, with every venue on it. Another identity's list is not readable.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "listKey": {
        "description": "the list's key, from list_lists",
        "type": "string"
      }
    },
    "required": [
      "listKey"
    ],
    "type": "object"
  },
  "name": "get_list",
  "title": "Get list"
}

🔴 list_lists read The identity's own lists, with a count and a cover for each. Read this at the start of a returning conversation: it is what the guest kept last time.

List lists

The identity's own lists, with a count and a cover for each. Read this at the start of a returning conversation: it is what the guest kept last time.

ParameterTypeDescription
limitintegerrows to return, at most 50
offsetintegerrows to skip; with totalCount in the result this pages through them

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "List lists"
  },
  "description": "The identity's own lists, with a count and a cover for each. Read this at the start of a returning conversation: it is what the guest kept last time.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "limit": {
        "description": "rows to return, at most 50",
        "type": "integer"
      },
      "offset": {
        "description": "rows to skip; with totalCount in the result this pages through them",
        "type": "integer"
      }
    },
    "required": [],
    "type": "object"
  },
  "name": "list_lists",
  "title": "List lists"
}

🔴 remove_restaurant_from_list destructive Take a venue off one of the identity's lists. Say which venue and which list to the guest before you call it — this removes data.

Remove restaurant from list

Take a venue off one of the identity's lists. Say which venue and which list to the guest before you call it — this removes data.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
listKey requiredstringthe list to remove from
restaurantKey requiredstringthe venue to remove

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": true,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Remove restaurant from list"
  },
  "description": "Take a venue off one of the identity's lists. Say which venue and which list to the guest before you call it — this removes data.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "listKey": {
        "description": "the list to remove from",
        "type": "string"
      },
      "restaurantKey": {
        "description": "the venue to remove",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey",
      "listKey",
      "restaurantKey"
    ],
    "type": "object"
  },
  "name": "remove_restaurant_from_list",
  "title": "Remove restaurant from list"
}

🔴 update_list write Rename one of the identity's lists. The venues on it are untouched.

Update list

Rename one of the identity's lists. The venues on it are untouched.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
listKey requiredstringthe list to rename
title requiredstringthe new name

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Update list"
  },
  "description": "Rename one of the identity's lists. The venues on it are untouched.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "listKey": {
        "description": "the list to rename",
        "type": "string"
      },
      "title": {
        "description": "the new name",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey",
      "listKey",
      "title"
    ],
    "type": "object"
  },
  "name": "update_list",
  "title": "Update list"
}

GROUP

🔴 close_group_match write Close a group match to further votes. The match and every vote stay readable; only voting stops. Close it once the group has decided, then book the winner.

Close group match

Close a group match to further votes. The match and every vote stay readable; only voting stops. Close it once the group has decided, then book the winner.

ParameterTypeDescription
groupMatchKey requiredstringthe match to close
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Close group match"
  },
  "description": "Close a group match to further votes. The match and every vote stay readable; only voting stops. Close it once the group has decided, then book the winner.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "groupMatchKey": {
        "description": "the match to close",
        "type": "string"
      },
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      }
    },
    "required": [
      "groupMatchKey",
      "idempotencyKey"
    ],
    "type": "object"
  },
  "name": "close_group_match",
  "title": "Close group match"
}

🔴 create_group_match write Start a group decision: a few venues, a few dates, and the people to ask. The answer carries a share link — give that to the guest to send on, because an invitee needs no TasteMatch identity to vote through it. Keep the options few: this is a decision, not a catalogue.

Create group match

Start a group decision: a few venues, a few dates, and the people to ask. The answer carries a share link — give that to the guest to send on, because an invitee needs no TasteMatch identity to vote through it. Keep the options few: this is a decision, not a catalogue.

ParameterTypeDescription
dateOptions requiredarray<string>the dates to choose between, RFC3339 with the region's UTC offset
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
restaurantKeys requiredarray<string>the venues to choose between
title requiredstringwhat the group is deciding, in the guest's words
inviteesarray<object>the people to ask, each by name and email
invitees[].displayName requiredstringthe name the group will see
invitees[].email requiredstringwhere the invitation goes

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Create group match"
  },
  "description": "Start a group decision: a few venues, a few dates, and the people to ask. The answer carries a share link — give that to the guest to send on, because an invitee needs no TasteMatch identity to vote through it. Keep the options few: this is a decision, not a catalogue.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "dateOptions": {
        "description": "the dates to choose between, RFC3339 with the region's UTC offset",
        "items": {
          "type": "string"
        },
        "type": "array"
      },
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "invitees": {
        "description": "the people to ask, each by name and email",
        "items": {
          "additionalProperties": false,
          "properties": {
            "displayName": {
              "description": "the name the group will see",
              "type": "string"
            },
            "email": {
              "description": "where the invitation goes",
              "type": "string"
            }
          },
          "required": [
            "displayName",
            "email"
          ],
          "type": "object"
        },
        "type": "array"
      },
      "restaurantKeys": {
        "description": "the venues to choose between",
        "items": {
          "type": "string"
        },
        "type": "array"
      },
      "title": {
        "description": "what the group is deciding, in the guest's words",
        "type": "string"
      }
    },
    "required": [
      "dateOptions",
      "idempotencyKey",
      "restaurantKeys",
      "title"
    ],
    "type": "object"
  },
  "name": "create_group_match",
  "title": "Create group match"
}

🔴 delete_group_match destructive Delete a group match. The share link stops working for everyone who holds it, and the votes go with it. Read the match and tell the guest what will go before you call this.

Delete group match

Delete a group match. The share link stops working for everyone who holds it, and the votes go with it. Read the match and tell the guest what will go before you call this.

ParameterTypeDescription
groupMatchKey requiredstringthe match to delete
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": true,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Delete group match"
  },
  "description": "Delete a group match. The share link stops working for everyone who holds it, and the votes go with it. Read the match and tell the guest what will go before you call this.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "groupMatchKey": {
        "description": "the match to delete",
        "type": "string"
      },
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      }
    },
    "required": [
      "groupMatchKey",
      "idempotencyKey"
    ],
    "type": "object"
  },
  "name": "delete_group_match",
  "title": "Delete group match"
}

🔴 get_group_match read One group match the identity created: the venues, the date options, who was invited, who has voted and for what, and the share link.

Get group match

One group match the identity created: the venues, the date options, who was invited, who has voted and for what, and the share link.

ParameterTypeDescription
groupMatchKey requiredstringthe match's key, from list_group_matches

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Get group match"
  },
  "description": "One group match the identity created: the venues, the date options, who was invited, who has voted and for what, and the share link.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "groupMatchKey": {
        "description": "the match's key, from list_group_matches",
        "type": "string"
      }
    },
    "required": [
      "groupMatchKey"
    ],
    "type": "object"
  },
  "name": "get_group_match",
  "title": "Get group match"
}

🔴 list_group_matches read The group matches this identity created, with how many were invited and how many have voted. Matches it was merely invited to are not here.

List group matches

The group matches this identity created, with how many were invited and how many have voted. Matches it was merely invited to are not here.

ParameterTypeDescription
limitintegerrows to return, at most 50
offsetintegerrows to skip; with totalCount in the result this pages through them

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "List group matches"
  },
  "description": "The group matches this identity created, with how many were invited and how many have voted. Matches it was merely invited to are not here.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "limit": {
        "description": "rows to return, at most 50",
        "type": "integer"
      },
      "offset": {
        "description": "rows to skip; with totalCount in the result this pages through them",
        "type": "integer"
      }
    },
    "required": [],
    "type": "object"
  },
  "name": "list_group_matches",
  "title": "List group matches"
}

🔴 submit_group_match_vote write Cast one person's vote in an open group match. Pass `memberId` for someone who was invited by name; pass `displayName` instead for someone joining off the share link. Vote only what that person actually said: possession of the match key is the whole authorisation, and a memberId you did not collect from that person overwrites their vote. The match must still be open.

Submit group match vote

Cast one person's vote in an open group match. Pass `memberId` for someone who was invited by name; pass `displayName` instead for someone joining off the share link. Vote only what that person actually said: possession of the match key is the whole authorisation, and a memberId you did not collect from that person overwrites their vote. The match must still be open.

ParameterTypeDescription
groupMatchKey requiredstringthe match being voted in
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
picks requiredarray<object>one pick per venue and date pair the person accepts
picks[].dateOptionIdx requiredintegerthe index of the date option, counting from zero
picks[].restaurantKey requiredstring
displayNamestringthe name of someone joining off the link, when they were not invited by name
memberIdstringthe invitee this vote belongs to, from get_group_match

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Submit group match vote"
  },
  "description": "Cast one person's vote in an open group match. Pass \`memberId\` for someone who was invited by name; pass \`displayName\` instead for someone joining off the share link. Vote only what that person actually said: possession of the match key is the whole authorisation, and a memberId you did not collect from that person overwrites their vote. The match must still be open.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "displayName": {
        "description": "the name of someone joining off the link, when they were not invited by name",
        "type": "string"
      },
      "groupMatchKey": {
        "description": "the match being voted in",
        "type": "string"
      },
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "memberId": {
        "description": "the invitee this vote belongs to, from get_group_match",
        "type": "string"
      },
      "picks": {
        "description": "one pick per venue and date pair the person accepts",
        "items": {
          "additionalProperties": false,
          "properties": {
            "dateOptionIdx": {
              "description": "the index of the date option, counting from zero",
              "type": "integer"
            },
            "restaurantKey": {
              "type": "string"
            }
          },
          "required": [
            "dateOptionIdx",
            "restaurantKey"
          ],
          "type": "object"
        },
        "type": "array"
      }
    },
    "required": [
      "groupMatchKey",
      "idempotencyKey",
      "picks"
    ],
    "type": "object"
  },
  "name": "submit_group_match_vote",
  "title": "Submit group match vote"
}

SHARE

🔴 cancel_shared_reservation destructive Cancel a reservation the guest holds an edit link for. This cannot be undone. Say the venue and the time back to the guest and wait for them before you call it. For a reservation the acting identity owns, use cancel_reservation instead, which checks that echo for you.

Cancel shared reservation

Cancel a reservation the guest holds an edit link for. This cannot be undone. Say the venue and the time back to the guest and wait for them before you call it. For a reservation the acting identity owns, use cancel_reservation instead, which checks that echo for you.

ParameterTypeDescription
editToken requiredstringthe token from the guest's own edit link
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": true,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Cancel shared reservation"
  },
  "description": "Cancel a reservation the guest holds an edit link for. This cannot be undone. Say the venue and the time back to the guest and wait for them before you call it. For a reservation the acting identity owns, use cancel_reservation instead, which checks that echo for you.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "editToken": {
        "description": "the token from the guest's own edit link",
        "type": "string"
      },
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      }
    },
    "required": [
      "editToken",
      "idempotencyKey"
    ],
    "type": "object"
  },
  "name": "cancel_shared_reservation",
  "title": "Cancel shared reservation"
}

🔴 create_share_key write Mint a link the guest can send to someone else. Read-kind only: whoever opens it can look, never edit. Minting twice for the same object returns the same link. Mint only for a venue the guest asked about or a reservation the acting identity owns — a link is readable by anyone who holds it, and a reservation's link shows the venue, the date and the party size.

Create share key

Mint a link the guest can send to someone else. Read-kind only: whoever opens it can look, never edit. Minting twice for the same object returns the same link. Mint only for a venue the guest asked about or a reservation the acting identity owns — a link is readable by anyone who holds it, and a reservation's link shows the venue, the date and the party size.

ParameterTypeDescription
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
kind requiredstringwhat to share: restaurant, reservation
objectKey requiredstringthe key of the venue or reservation to share

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Create share key"
  },
  "description": "Mint a link the guest can send to someone else. Read-kind only: whoever opens it can look, never edit. Minting twice for the same object returns the same link. Mint only for a venue the guest asked about or a reservation the acting identity owns — a link is readable by anyone who holds it, and a reservation's link shows the venue, the date and the party size.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "kind": {
        "description": "what to share: restaurant, reservation",
        "type": "string"
      },
      "objectKey": {
        "description": "the key of the venue or reservation to share",
        "type": "string"
      }
    },
    "required": [
      "idempotencyKey",
      "kind",
      "objectKey"
    ],
    "type": "object"
  },
  "name": "create_share_key",
  "title": "Create share key"
}

🟢 get_share_sitemap read The public index of every shareable venue and list, as XML. Large: read it to discover what exists at all, not to answer one question.

Get share sitemap

The public index of every shareable venue and list, as XML. Large: read it to discover what exists at all, not to answer one question.

No parameters.

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Get share sitemap"
  },
  "description": "The public index of every shareable venue and list, as XML. Large: read it to discover what exists at all, not to answer one question.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {},
    "required": [],
    "type": "object"
  },
  "name": "get_share_sitemap",
  "title": "Get share sitemap"
}

🟢 resolve_share_public_id read Turn a public page id — the readable one in a tastematch.io venue or list URL — into the object it names and its key.

Resolve share public id

Turn a public page id — the readable one in a tastematch.io venue or list URL — into the object it names and its key.

ParameterTypeDescription
objectType requiredstringrestaurant or list
publicId requiredstringthe readable id from the public URL

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Resolve share public id"
  },
  "description": "Turn a public page id — the readable one in a tastematch.io venue or list URL — into the object it names and its key.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "objectType": {
        "description": "restaurant or list",
        "type": "string"
      },
      "publicId": {
        "description": "the readable id from the public URL",
        "type": "string"
      }
    },
    "required": [
      "objectType",
      "publicId"
    ],
    "type": "object"
  },
  "name": "resolve_share_public_id",
  "title": "Resolve share public id"
}

🟢 resolve_share_token read Turn a share link the guest pasted into the thing it points at — a venue, a reservation or a group match — and the key to carry on with. Pass the token, which is the last path segment of the link. A link that has expired or was never ours is simply not found.

Resolve share token

Turn a share link the guest pasted into the thing it points at — a venue, a reservation or a group match — and the key to carry on with. Pass the token, which is the last path segment of the link. A link that has expired or was never ours is simply not found.

ParameterTypeDescription
token requiredstringthe token from the share link, its last path segment

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Resolve share token"
  },
  "description": "Turn a share link the guest pasted into the thing it points at — a venue, a reservation or a group match — and the key to carry on with. Pass the token, which is the last path segment of the link. A link that has expired or was never ours is simply not found.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "token": {
        "description": "the token from the share link, its last path segment",
        "type": "string"
      }
    },
    "required": [
      "token"
    ],
    "type": "object"
  },
  "name": "resolve_share_token",
  "title": "Resolve share token"
}

🔴 update_shared_reservation write Change a reservation the guest holds an edit link for — one made somewhere else, not through us. The link is the authorisation, so ask the guest for it and use it only for the reservation they named. For a reservation the acting identity owns, use update_reservation instead.

Update shared reservation

Change a reservation the guest holds an edit link for — one made somewhere else, not through us. The link is the authorisation, so ask the guest for it and use it only for the reservation they named. For a reservation the acting identity owns, use update_reservation instead.

ParameterTypeDescription
editToken requiredstringthe token from the guest's own edit link
idempotencyKey requiredstringa key of your own for this one write; sending the same key again returns the first result instead of writing twice
dateTimestringthe new time, RFC3339 with the region's UTC offset
paxintegerthe new party size

Wire definition (tools/list)

{
  "annotations": {
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false,
    "readOnlyHint": false,
    "title": "Update shared reservation"
  },
  "description": "Change a reservation the guest holds an edit link for — one made somewhere else, not through us. The link is the authorisation, so ask the guest for it and use it only for the reservation they named. For a reservation the acting identity owns, use update_reservation instead.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "dateTime": {
        "description": "the new time, RFC3339 with the region's UTC offset",
        "type": "string"
      },
      "editToken": {
        "description": "the token from the guest's own edit link",
        "type": "string"
      },
      "idempotencyKey": {
        "description": "a key of your own for this one write; sending the same key again returns the first result instead of writing twice",
        "type": "string"
      },
      "pax": {
        "description": "the new party size",
        "type": "integer"
      }
    },
    "required": [
      "editToken",
      "idempotencyKey"
    ],
    "type": "object"
  },
  "name": "update_shared_reservation",
  "title": "Update shared reservation"
}

UTILITY

🟢 get_skill read Read one or more playbooks in full. Ask for several at once rather than one per turn.

Get skill

Read one or more playbooks in full. Ask for several at once rather than one per turn.

ParameterTypeDescription
names requiredarray<string>the playbooks to read, from list_skills

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Get skill"
  },
  "description": "Read one or more playbooks in full. Ask for several at once rather than one per turn.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "names": {
        "description": "the playbooks to read, from list_skills",
        "items": {
          "type": "string"
        },
        "type": "array"
      }
    },
    "required": [
      "names"
    ],
    "type": "object"
  },
  "name": "get_skill",
  "title": "Get skill"
}

🟢 get_vocabulary read Every value the filters accept, by axis, with the rule for combining them. Read it before your first filter and keep it for the conversation — a guessed descriptor is refused, and a guessed cuisine slug quietly matches nothing.

Get vocabulary

Every value the filters accept, by axis, with the rule for combining them. Read it before your first filter and keep it for the conversation — a guessed descriptor is refused, and a guessed cuisine slug quietly matches nothing.

No parameters.

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Get vocabulary"
  },
  "description": "Every value the filters accept, by axis, with the rule for combining them. Read it before your first filter and keep it for the conversation — a guessed descriptor is refused, and a guessed cuisine slug quietly matches nothing.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {},
    "required": [],
    "type": "object"
  },
  "name": "get_vocabulary",
  "title": "Get vocabulary"
}

🟢 list_skills read The playbooks available, one line each. Read a playbook before a journey you have not done before; they carry the sequence and the traps that the tool descriptions cannot.

List skills

The playbooks available, one line each. Read a playbook before a journey you have not done before; they carry the sequence and the traps that the tool descriptions cannot.

No parameters.

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "List skills"
  },
  "description": "The playbooks available, one line each. Read a playbook before a journey you have not done before; they carry the sequence and the traps that the tool descriptions cannot.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {},
    "required": [],
    "type": "object"
  },
  "name": "list_skills",
  "title": "List skills"
}

🟡 resolve_key read Turn a name the guest said into the keys it might mean, best first. `kind` says what you are looking for: restaurant, region, list, reservation. A `list` or a `reservation` is the signed-in person's own and needs a sign-in. Resolve once per thing and then thread the key: a name resolved again later can land on a different venue. Say the label back to the guest when more than one candidate came close.

Resolve key

Turn a name the guest said into the keys it might mean, best first. `kind` says what you are looking for: restaurant, region, list, reservation. A `list` or a `reservation` is the signed-in person's own and needs a sign-in. Resolve once per thing and then thread the key: a name resolved again later can land on a different venue. Say the label back to the guest when more than one candidate came close.

ParameterTypeDescription
kind requiredstringwhat to resolve: restaurant, region, list, reservation
latnumberlatitude, to resolve a region from a point instead of a name
lngnumberlongitude, paired with lat
regionIdstringbound a restaurant search to one region
textstringthe name as the guest said it

Wire definition (tools/list)

{
  "annotations": {
    "idempotentHint": false,
    "openWorldHint": false,
    "readOnlyHint": true,
    "title": "Resolve key"
  },
  "description": "Turn a name the guest said into the keys it might mean, best first. \`kind\` says what you are looking for: restaurant, region, list, reservation. A \`list\` or a \`reservation\` is the signed-in person's own and needs a sign-in. Resolve once per thing and then thread the key: a name resolved again later can land on a different venue. Say the label back to the guest when more than one candidate came close.",
  "inputSchema": {
    "additionalProperties": false,
    "properties": {
      "kind": {
        "description": "what to resolve: restaurant, region, list, reservation",
        "type": "string"
      },
      "lat": {
        "description": "latitude, to resolve a region from a point instead of a name",
        "type": "number"
      },
      "lng": {
        "description": "longitude, paired with lat",
        "type": "number"
      },
      "regionId": {
        "description": "bound a restaurant search to one region",
        "type": "string"
      },
      "text": {
        "description": "the name as the guest said it",
        "type": "string"
      }
    },
    "required": [
      "kind"
    ],
    "type": "object"
  },
  "name": "resolve_key",
  "title": "Resolve key"
}

INSTRUCTIONS

You are an agent using the TasteMatch core — restaurant discovery, taste matching and reservations. You do not need to understand the TasteMatch vector or our labelling to be useful. Use any filter with whichever interpretation you place on it. Never invent a descriptor — call get_vocabulary. You act for one person: whoever signed in to this connection. Until someone has, discovery works, and a tool that needs a person asks them to sign in. Journeys: DISCOVER, PLACE, RESTAURANT, AVAILABILITY, RESERVATION, IDENTITY, TASTE, LISTS, GROUP, SHARE, UTILITY. Name grammar — every tool conforms: get_ | list_ | search_ | filter_ | count_ | resolve_ read create_ | update_ | delete_ | {verb}_ write Route by intent: A name, not a key -> resolve_key, then operate on the key "restaurants like X" -> filter_restaurants, facets from get_vocabulary "how many" -> count_restaurants, never filter then count rows A specific venue -> get_restaurant, with fields[] A named dish -> search_dishes Booking -> get_reservation_info -> list_availability_slots -> create_instant_reservation or create_reservation_request Keeping something for later -> a list Keys are yours to keep. Resolve a name once, then thread the key through the rest of the journey. Do not re-resolve a name you already hold a key for. Lists are your store. Put a shortlist, a comparison set or the places you have discussed into a named list: it belongs to the acting identity and is still there next session, where your context is not. Identity is collected at the point it is needed, never before. Discovery writes nothing and needs no sign-in. Reserving needs the reservation rung: a name, one contact channel, and accepted Terms. A tool that refuses for identity names the rung you lack and the tool that climbs to it. A value already on file is never replaced by anything you send. There is no social surface: no follows, blocks, followers, user search, notifications or profile browsing. Group match is the one many-person feature, and it works by share link — invitees need no TasteMatch identity. Data efficiency: default limit 10, totalCount always reported. Always filter. Ask for fields[] rather than whole documents. Batch, do not loop. Booking: read the venue's booking mode first; instant and request are different tools. Book a slot you read from list_availability_slots. Leave approxMinutes at 0 unless the guest has told you they are flexible — a non-zero value lets the venue book a different time than you asked for, and the answer says so in adjusted and bookedDate. Writes: pass idempotencyKey — the same key twice returns the first result rather than writing twice. Destructive tools are annotated; read the target and tell the guest what will be removed before you call one. cancel_reservation needs confirming first: read the reservation, say the venue and the time back to the guest, wait, and echo both in the call. Never cancel on a key alone, however sure you are of it. On failure read the message. A validation, not-found or forbidden refusal is ours and tells you how to fix the call — fix it, do not repeat it. A bare code is not retryable; report it. Present results as readable summaries, not raw JSON, unless otherwise requested. Playbooks for a journey you have not done before: list_skills, then get_skill.

SKILLS

discover-to-reserve — the whole journey: find a venue, read how it books, take the table

Place first, then venue, then booking. 1. Turn where the guest is into a regionId: resolve_key with kind region, or list_regions. 2. Find venues: filter_restaurants for a kind of place, search_restaurants for a named one, search_dishes for a named dish. Read get_vocabulary once before your first filter. 3. Narrow with count_restaurants before pulling rows when the guest's description is vague. 4. Read the venue: get_restaurant, lean by default, fields[] for the rest. 5. Read how it books: get_reservation_info. This decides the next tool and is never a guess. 6. Read what is free: list_availability_slots. Offer the guest real times. 7. Collect identity only now: the guest signs in, then promote_identity to reach the rung that can reserve. 8. Take the table: create_instant_reservation at an instant venue, create_reservation_request at a request venue, create_reservation_offer at one that books through its own widget. Tell the guest which of the three happened. A request is not yet a table; an offer is not yet a table either until they finish in the widget and get_reservation_status says so.

sign-in-and-identity — who you act for, the rungs, which tool climbs, what each rung reaches

You act for one person: the one signed in to this connection. The sign-in is the identity; nothing else selects whose data is touched, and no argument can. Before anyone signs in, discovery works. A tool that acts for a person asks them to sign in when you call it, so call it when the guest needs it rather than asking them to sign in first. Rungs, derived from what the identity holds: anonymous signed in reaches discovery, lists, group match, taste reservation + a first and last name, a contact reaches reserving profile + validated contact nothing extra here Climb with promote_identity. A refusal for identity names the rung you lack and the tool that climbs to it — read it rather than retrying. An instant venue needs both an email and a phone, so collect both when the guest wants a confirmed table rather than a request. A value already on file is never replaced by anything you send. Read get_identity before asking the guest for something we already hold.

label-vocabulary — the descriptor axes, validate-not-map, and how facets combine

Call get_vocabulary and use its words exactly. Never invent one, never translate one, never shorten one. Axes: dims (what a venue is like), occasions (what it suits), menuMetas (which service), menuDescriptors (what the menu carries), cuisine (what kitchen). AND across facets, OR within one. Every value narrows. Pass what the guest asked for and nothing else — a filter nobody asked for silently removes venues they would have liked. menuDescriptors are the venue's side, never the guest's. A coeliac does not need "a gluten-free guest"; they need a menu that prints gluten-free dishes. An unknown value is refused with a message naming the facet. An invented cuisine slug would otherwise come back as an empty list that reads like "there is nothing of that kind here".

availability-semantics — instant versus request, the slot ladder, approxMinutes and adjusted

A venue's booking mode is its own. Read it with get_reservation_info before you choose a tool. instant tables confirmed live -> create_instant_reservation request someone at the venue accepts -> create_reservation_request Slot times are the venue's own ladder on its own wall clock. They sit on no grid, so 19:00 is often not bookable where 19:15 is. Read list_availability_slots and book a time it gave you. Pass pax and the tool drops slots too small for the party, including per-area minimums. Pass the areaId of the slot you chose to hold the seating; it narrows the search and never moves the booking. approxMinutes defaults to 0, meaning this time or nothing. Raise it only when the guest has said they are flexible, and then read `adjusted` and `bookedDate` in the answer and tell them what they actually got. Empty slots and empty windows mean shut that day or past the booking horizon. Offer another day rather than retrying.

group-match — create, invite by link, collect votes from people with no identity, close

Group match is the one many-person feature, and it works by link. 1. create_group_match with a few venues and a few dates. Keep both short: this is a decision, not a catalogue. 2. The answer carries a share link. Give it to the guest to distribute. Whoever opens it can vote with no TasteMatch identity at all. 3. get_group_match shows who has voted and for what. submit_group_match_vote is for a vote that reaches you instead of the link — memberId for someone invited by name, displayName for someone new. 4. close_group_match when the group has decided. Votes stay readable. 5. Then book the winner through the booking journey, for whoever is hosting.

regions-and-places — resolving a place, and what regionId is for

Everything region-scoped takes a regionId, and a regionId comes from us, never from the guest. resolve_key with kind region takes a town, a district, an address, or a lat and lng. list_regions lists what we cover at all; search_places matches a smaller place to the region containing it. A region carries the IANA timezone its venues' times are written on. Every dateTime you send should carry that region's UTC offset, and every slot time you read is on that clock. An empty result means we hold no venues there. Say that rather than widening the search silently.

lists-as-store — what belongs in a list rather than in context

Your context ends with the conversation. A list does not. Put a shortlist, a comparison set, or the places the guest has already turned down into a named list with create_list and add_restaurant_to_list. Name it for what it is for; the guest sees that name again. Start a returning conversation with list_lists. It is what they kept last time. Lists belong to the acting identity and are private here — sharing, browsing someone else's and searching across them are social, and this surface has no social half. Prune rather than accumulate: remove_restaurant_from_list removes data, so say which venue and which list to the guest first.

bulk-and-pagination — count before filter, batch over loop, default limits, fields[]

Ask for less. count_restaurants answers "how many" with no rows. Use it while narrowing, and pull rows once. Every list and search tool takes limit and offset and reports totalCount. The default limit is 10. Page with offset rather than running the search again. get_restaurant has a lean default projection. Name fields[] only for what you will actually say to the guest; the label vector and the menu cards are large. Batch what batches: one impressions call per turn, several skills in one get_skill. Resolve a name once and thread the key. Re-resolving is both a round trip and a chance to land on a different venue.