Synvya/mcp-server
If you are the rightful owner of mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
MCP server designed for AI assistants to help users discover restaurants.
Synvya MCP Server
Discover and book restaurants and other food establishments directly from your AI assistant.
Available Tools
search_food_establishments
Find food establishments (restaurants, bakeries, cafes, etc.) by type, cuisine, dietary needs, or free-text search. All filters are combined with AND logic. Returns an array of JSON-LD formatted food establishment objects following the schema.org FoodEstablishment specification. The output may contain mixed types (Restaurant, Bakery, etc.).
Parameters:
foodEstablishmentType(optional): Filter by schema.org FoodEstablishment type- Valid values:
Bakery,BarOrPub,Brewery,CafeOrCoffeeShop,Distillery,FastFoodRestaurant,IceCreamShop,Restaurant,Winery - If not provided, returns all FoodEstablishment types
- Valid values:
cuisine(optional): Cuisine type (e.g., "Spanish", "Italian", "Mexican")- Searches
schema.org:servesCuisineproperty first, then falls back to description text matching
- Searches
query(optional): Free-text search for establishment name, location, or description- Matches establishment name, description text, or location data from
schema.org:PostalAddressproperty - Example: "Snoqualmie" to find establishments in that location
- Matches establishment name, description text, or location data from
dietary(optional): Dietary requirement (e.g., "vegan", "gluten free")- Matches against lowercase dietary keywords in food establishment profiles
- Keywords are normalized for flexible matching (handles "gluten free" vs "gluten-free")
Returns:
food_establishments: Array of JSON-LD formatted food establishment objects, each containing:@context(string): JSON-LD context ("https://schema.org")@type(string): Schema.org FoodEstablishment type (Bakery, BarOrPub, Brewery, CafeOrCoffeeShop, Distillery, FastFoodRestaurant, IceCreamShop, Restaurant, or Winery)name(string): Restaurant display namedescription(string): Full restaurant description@id(string): Food establishment identifier - use this asrestaurant_idforget_menu_itemsaddress(object, optional): PostalAddress with streetAddress, addressLocality, addressRegion, postalCode, addressCountrytelephone(string, optional): Phone numberemail(string, optional): Email inmailto:formatopeningHours(array, optional): Opening hours in format["Tu-Th 11:00-21:00", "Fr-Sa 11:00-00:00", "Su 11:00-21:00"]image(string, optional): Banner image URLservesCuisine(array, optional): Array of cuisine typesgeo(object, optional): GeoCoordinates with latitude and longitudeurl(string, optional): Website URLacceptsReservations(string, optional): "True", "False", or URLkeywords(string, optional): Comma-separated keywordshasMenu(array, optional): Array of menu objects, each containing:@type(string): "Menu"name(string): Menu namedescription(string, optional): Menu descriptionidentifier(string): Menu identifier - use this asmenu_identifierforget_menu_items
Example:
{"foodEstablishmentType": "Restaurant", "cuisine": "Spanish", "dietary": "vegan"}
{"foodEstablishmentType": "Bakery", "dietary": "gluten free"}
{"query": "Snoqualmie"}
{"cuisine": "Italian", "query": "pizza"}
Behavior Notes:
- All filters use AND logic (must match all specified criteria)
- If
foodEstablishmentTypeparameter is provided, only establishments of that type are returned - If
foodEstablishmentTypeis not provided, all valid FoodEstablishment types are returned (mixed types in array) - Cuisine matching prioritizes schema.org tags for SEO compatibility
- Dietary tags are case-insensitive and handle variations
- Returns full description text (not truncated)
- Output format is JSON-LD (JSON for Linked Data) following schema.org FoodEstablishment specification
- All establishment objects include
@context,@id, and@typefor proper JSON-LD interpretation
get_menu_items
Get all dishes from a specific food establishment menu. Returns a complete Menu object with menu items organized by sections.
Parameters:
restaurant_id(required): Food establishment identifier- MUST be the exact
@idvalue fromsearch_food_establishmentsresults
- MUST be the exact
menu_identifier(required): Menu identifier- MUST be the exact
identifiervalue from thehasMenuarray insearch_food_establishmentsresults
- MUST be the exact
Returns: A JSON-LD Menu object following schema.org Menu specification:
@context: "https://schema.org"@type: "Menu"name(string): Menu namedescription(string, optional): Menu descriptionidentifier(string): Menu identifierhasMenuSection(array): Array of MenuSection objects, each containing:@type: "MenuSection"name(string): Section name (e.g., "Appetizers", "Entrees", "Sides")description(string, optional): Section descriptionidentifier(string): Section identifierhasMenuItem(array): Array of MenuItem objects in this section, each containing:@context: "https://schema.org"@type: "MenuItem"name(string): name of the menu itemdescription(string): Description of the menu itemidentifier(string, optional): Menu item identifierimage(string, optional): Image URL for the menu itemsuitableForDiet(array, optional): Array of schema.org suitableForDiet values (e.g., "VeganDiet", "GlutenFreeDiet")offers(object, optional): Price information with@type: "Offer",price(number),priceCurrency(string)geo(object, optional): Geographic coordinates with@type: "GeoCoordinates",latitude, andlongitude
Example:
{
"restaurant_id": "nostr:npub1...",
"menu_identifier": "Dinner"
}
Behavior Notes:
- Output format is JSON-LD (JSON for Linked Data) following schema.org Menu, MenuSection, and MenuItem specifications
- Menu items are grouped by sections (e.g., Entrees, Sides, Appetizers)
- All objects include
@contextand/or@typefor proper JSON-LD interpretation - Dietary tags are mapped to schema.org suitableForDiet values
- Unmapped dietary tags are appended to the description as text (e.g., "Nut free. Sulphites")
- If menu not found, returns an error with empty hasMenuSection array
- If food establishment not found, returns an error with empty hasMenuSection array
search_menu_items
Find specific dishes across all food establishments by name, ingredient, or dietary preference. Returns a JSON-LD graph structure with food establishments grouped by their matching menu items.
Parameters:
dish_query(required): Dish name, ingredient, or dietary term to search for- Searches dish names and descriptions
- Auto-detects dietary terms: If query looks like a dietary term (vegan, vegetarian, gluten-free, etc.), it will also match dishes with matching dietary tags even if the word isn't in the dish name
- Example: "pizza" searches for pizza dishes, "vegan" finds all vegan dishes (by tag)
dietary(optional): Additional dietary filter- Combined with
dish_queryusing AND logic - If
dish_queryis already a dietary term, this adds an additional constraint
- Combined with
restaurant_id(optional): Filter results to a specific food establishment- Use the
@idfromsearch_food_establishmentsresults
- Use the
Returns: A JSON-LD graph structure following schema.org specifications:
@context: "https://schema.org"@graph: Array of FoodEstablishment objects, each containing:@type(string): Schema.org FoodEstablishment type (Restaurant, Bakery, etc.)name(string): Food establishment namegeo(object, optional): GeoCoordinates with latitude and longitude@id(string): Food establishment identifier in bech32 format (nostr:npub1...)hasMenu(array): Array of Menu objects, each containing:@type(string): "Menu"name(string): Menu namedescription(string, optional): Menu descriptionidentifier(string): Menu identifierhasMenuItem(array): Array of MenuItem objects, each containing:@context: "https://schema.org"@type: "MenuItem"name(string): Name of the menu itemdescription(string): Description of the menu itemidentifier(string, optional): Menu item identifierimage(string, optional): Image URL for the menu itemsuitableForDiet(array, optional): Array of schema.org suitableForDiet values (e.g., "VeganDiet", "GlutenFreeDiet")offers(object, optional): Price information with@type: "Offer",price(number), andpriceCurrency(string)geo(object, optional): Geographic coordinates with@type: "GeoCoordinates",latitude, andlongitude
Example:
{"dish_query": "pizza"}
{"dish_query": "vegan"} // Auto-detects as dietary term
{"dish_query": "pizza", "dietary": "vegan"}
{"dish_query": "tomato", "restaurant_id": "nostr:npub1..."}
Behavior Notes:
- Automatically detects common dietary terms: vegan, vegetarian, gluten-free, gluten free, dairy-free, dairy free, nut-free, nut free
- When a dietary term is detected, matches both text search AND dietary tags
- Products use uppercase dietary tags with underscores (e.g., "VEGAN", "GLUTEN_FREE") - normalized for matching
- Results are grouped by food establishment and menu - each establishment appears once with all matching menu items organized by menu
- Output format is JSON-LD (JSON for Linked Data) following schema.org specifications
- All objects include
@contextand@typefor proper JSON-LD interpretation - Dietary tags are mapped to schema.org suitableForDiet values
- Unmapped dietary tags are appended to the description as text (e.g., "Nut free. Sulphites")
Testing
Local Testing
The server supports both HTTP (for testing) and stdio (for Claude Desktop) transports.
HTTP Mode (for MCP Inspector testing)
-
Start the server in HTTP mode:
MCP_TRANSPORT=http npm run dev # or npm run dev -- --httpThe server will start on
http://localhost:3000(or the port specified inPORTenvironment variable). -
Test with MCP Inspector (in another terminal):
npm install -g @modelcontextprotocol/inspector mcp-inspector --transport http --server-url http://localhost:3000The inspector will open in your browser. You can then:
- Click "List Tools" to see available tools
- Test each tool with sample parameters
- View structured responses
Stdio Mode (for Claude Desktop)
-
Build the server:
npm run build -
Configure Claude Desktop - Add to
claude_desktop_config.json:{ "mcpServers": { "synvya": { "command": "node", "args": ["/absolute/path/to/mcp-server/dist/server.js"] } } } -
Restart Claude Desktop - The server will automatically start when Claude connects.
Example test queries:
- Search food establishments:
{"foodEstablishmentType": "Restaurant", "cuisine": "Spanish", "dietary": "vegan"}or{"query": "Snoqualmie"}or{"foodEstablishmentType": "Bakery", "dietary": "gluten free"} - Get menu items:
{"restaurant_id": "nostr:npub1...", "menu_identifier": "Dinner"} - Search dishes:
{"dish_query": "pizza"}or{"dish_query": "vegan"}(auto-detects dietary term)
Deployment
Deploy to Vercel
The MCP server can be deployed to Vercel as a serverless function, making it accessible to ChatGPT over HTTPS.
Prerequisites
- A Vercel account (Hobby plan or higher)
- The Vercel CLI installed (optional, for local testing):
npm install -g vercel
Deployment Steps
-
Push your code to GitHub (if not already done):
git push origin main -
Import project in Vercel:
- Go to vercel.com
- Click "Add New..." → "Project"
- Import your GitHub repository (
synvya/mcp-server) - Configure project settings:
- Framework Preset: "Other"
- Root Directory:
./ - Build Command:
npm run build(or leave default) - Output Directory: Leave empty
- Install Command:
npm install(or leave default)
-
Deploy:
- Click "Deploy"
- Wait for the deployment to complete
- Note your deployment URL (e.g.,
https://mcp.synvya.com)
-
Test the deployment:
npx @modelcontextprotocol/inspector@latest https://your-app.vercel.app/mcpThe MCP endpoint will be available at:
- Primary:
https://your-app.vercel.app/api/mcp - Alias:
https://your-app.vercel.app/mcp(via rewrite rule)
- Primary:
Connect to ChatGPT
-
Enable Developer Mode in ChatGPT:
- Go to ChatGPT settings
- Enable "Developer Mode" or "Connectors"
-
Add MCP Server:
- In ChatGPT, go to the Connectors/Integrations section
- Add a new MCP server connector
- Enter your server URL:
https://your-app.vercel.app/mcp - Configure authentication if needed (currently not required)
-
Test the connection:
- ChatGPT should now be able to use your MCP tools
- Try asking: "Find me a vegan Spanish restaurant"
Environment Variables
If you need to configure environment variables:
- Go to your Vercel project settings
- Navigate to "Environment Variables"
- Add any required variables (currently none needed)
Troubleshooting
- Data files not found: Ensure
data/directory is committed to git and not in.vercelignore - Build failures: Check that
npm run buildcompletes successfully locally - Cold starts: First request may be slower due to serverless cold starts
- CORS issues: The server includes CORS headers for browser-based testing
Data Files
The server reads from JSON files in the data/ directory:
profiles.json- Restaurant profiles (kind:0 events)collections.json- Menu collections (kind:30405 events)products.json- Individual dishes (kind:30402 events)