GrabFood MCP (via SEA MCP)
Server Details
Search GrabFood restaurants, full menus and dish prices by city, neighbourhood or radius.
- Status
- Healthy
- Uptime
- 87.9% over 21 days
- OAuth
- Works in Glama
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- SeaMCP/grabfood-mcp
- GitHub Stars
- 0
TDQS
Scored across 4 tools
Each tool targets a distinct resource and action: get a restaurant by ID, list areas, search restaurants, and search menu items. The names and descriptions make the boundaries clear, so an agent can easily choose the right tool.
All tool names follow the same 'Grab_verb_noun' pattern (get_restaurant, list_areas, search_menu_items, search_restaurants), with consistent snake_case and verb choice.
Four tools provide a well-scoped, complete set for exploring GrabFood data: area discovery, restaurant lookup, restaurant search, and menu item search. Each tool is necessary and there is no redundancy.
The core read-only workflows are covered: finding locations, searching restaurants, searching items, and retrieving full restaurant details. Minor gaps exist (e.g., no direct get-menu-item-by-id or batch restaurant retrieval), but these are workable via search.
Available Tools
4 toolsGrab_get_restaurantARead-onlyInspect
Fetch one GrabFood restaurant by id with its full menu, grouped by category in Grab's order. Prices are in the restaurant's currencyCode (IDR, MYR, PHP, VND, KHR, SGD, MMK), not converted; discountedPrice is null when there is no discount. Items carry Grab's badge (most_ordered, most_liked, signature_dish) and healthTags. Set includeModifiers for each item's option groups (min/max picks, max null = no limit, choices with extra charge) — this can be large. Also returns openingHours ({ mon: "10:00-22:00", … } in local time, closed days left out) and stats: menu figures such as itemCount, min/median/avg/maxPrice, discountedRatio (0–1), firstItemAt/lastItemAt (roughly when the restaurant joined Grab and last added an item) and weeklyOpenHours. Returns { data: null } when missing.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Grab merchant id, e.g. 6-C2ABCDEF. | |
| includeMenu | No | ||
| includeModifiers | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only safety profile, but the description goes well beyond them: currency semantics (prices unconverted, per currencyCode), discountedPrice null semantics, badge/healthTags presence, openingHours format and closed-day handling, stats field meanings, and the { data: null } missing-case. This is rich behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded and the rest is dense but purposeful, with each clause carrying distinct semantic content. It is long, and the stats enumeration could be trimmed, but with no output schema the detail largely earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the burden of describing return values — and it does: menu grouping, prices, badges, modifiers, openingHours, stats, and the null case. An agent has what it needs to call and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 33% (includeMenu and includeModifiers have no schema descriptions), so the description must compensate. It explains includeModifiers thoroughly (option groups, min/max picks, max null = no limit, extra charge), but includeMenu is left to inference from "full menu".
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Fetch one GrabFood restaurant by id") plus the scope of the payload ("full menu, grouped by category"). The by-id framing implicitly and clearly separates it from the sibling search/list tools that operate over sets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is clear from "by id", and the description gives concrete invocation guidance: set includeModifiers to get option groups and warns that this "can be large". It never names an alternative tool explicitly, so it stops short of the 5-level when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Grab_list_areasARead-onlyInspect
List the location values GrabFood data uses, with restaurant counts, so you know what to pass as city.
Without city: returns Grab cities (service regions) per country. With city: returns that city's delivery zones (Grab's "suburb" labels, e.g. "Bekasi 3", "JKT.W-KEBONJERUK", "Serpong BSD"); names are inconsistent and about half of restaurants (70% in Indonesia) have none, so prefer the area substring on the search tools for neighbourhoods.
Coverage: ~1M restaurants: Indonesia 711k (164 Grab cities), Malaysia 119k, Vietnam 92k, Philippines 53k, Cambodia 15k, Singapore 4.5k, Myanmar 3k. Menus were fetched between Jun and Sep 2026 (fetchedAt per restaurant).
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | Return this city's delivery zones. | |
| query | No | Substring on the city or zone name. | |
| country | No | ISO country code, uppercase. Only these countries have data. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint, destructiveHint, openWorldHint), and the description adds substantial non-obvious context the annotations cannot: coverage volumes per country, data-quality caveats (inconsistent zone names, ~half of restaurants lacking an area), and a staleness window ('menus were fetched between Jun and Sep 2026').
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded, then parameter behaviour, then caveats and coverage. It is dense and mostly earns its length, though the per-country restaurant counts are closer to trivia than decision-relevant information for selecting or calling the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With three optional parameters and no output schema, the description carries the full burden and does so: it explains both result shapes, the enum's scope ('only these countries have data'), the naming quality caveat, and the data vintage. An agent can call this correctly without further exploration.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so 3 is the baseline. The description goes beyond the terse schema text by explaining what each mode returns and by warning that zone names are unreliable ('Bekasi 3', 'JKT.W-KEBONJERUK'), which materially affects how an agent should interpret a city value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific verb and resource ('List the location values ... with restaurant counts') and immediately ties it to its downstream use ('so you know what to pass as city'). It also distinguishes itself from the search siblings by naming them as the preferred path for neighbourhood lookups.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit branching behaviour (call without city for Grab cities, with city for delivery zones) and an explicit routing rule away from this tool: 'prefer the area substring on the search tools for neighbourhoods'. That is a when-to-use, when-not-to-use, and alternative in one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Grab_search_restaurantsARead-onlyInspect
Search GrabFood restaurants. Filters are ANDed. Defaults to most rating votes (a rough popularity signal), or nearest first when near is set.
How to target a place:
city: Grab's service region, exact name (case-insensitive). Regions are coarse: "Jakarta" is all of Jabodetabek (incl. Bogor, Depok, Tangerang, Bekasi), "Bali" is the whole island. Call Grab_list_areas for the list.
area: substring of the full address, which holds street, kelurahan, kecamatan, kota and postcode, e.g. "Kemang", "Kebayoran Baru", "Denpasar", "Sleman". Also matches Grab's delivery zone label. Use this for neighbourhoods. It is a plain substring: "Kemang" also matches "Kemanggisan", so add a street or pair it with postcode or city.
postcode: prefix, e.g. "121" for South Jakarta 121xx.
near: lat/lng radius. Only Singapore and ~8% of Indonesian restaurants have coordinates; the rest never match.
cuisine matches Grab's cuisine labels by substring ("chicken" → Fried Chicken, Chicken Satay, …); matchedCuisines lists them. sellsItem finds restaurants with a menu item whose name contains the text (slower, ~1s); combined with alcohol true, that same item must match. rating is 0–5; restaurants without ratings sort last. Dietary flags come from Grab and are weak: isVegetarian is set on about half of all items, drinks included, so almost every restaurant "has a vegetarian item"; isAlcohol is set on only ~57k of 34M items, so also search item names ("bir", "beer", "wine", "arak").
Menu stats filters use figures precomputed per restaurant: minItems (menu size), medianPriceMin/Max (typical dish price in the local currency, so set country), ratios 0–1 as shares of the restaurant's items (minVegetarianRatio 0.5 = at least half its items are tagged vegetarian), minWeeklyOpenHours (168 = 24/7), joinedAfter/joinedBefore (oldest menu item, roughly when it joined Grab) and menuUpdatedAfter (newest menu item).
Coverage: ~1M restaurants: Indonesia 711k (164 Grab cities), Malaysia 119k, Vietnam 92k, Philippines 53k, Cambodia 15k, Singapore 4.5k, Myanmar 3k. Menus were fetched between Jun and Sep 2026 (fetchedAt per restaurant).
Returns { data, total, page, limit }. Each row includes a Grab url, openingHours ({ mon: "10:00-14:00, 17:00-22:00", … } in local time, closed days left out), and distanceKm when near is set.
| Name | Required | Description | Default |
|---|---|---|---|
| area | No | Address substring: neighbourhood, kecamatan, kota, street. | |
| city | No | Grab city, exact name. See Grab_list_areas. | |
| near | No | Only restaurants within radiusKm of this point. | |
| page | No | ||
| chain | No | Chain name substring. | |
| limit | No | ||
| query | No | Substring on name or chain name. | |
| sortBy | No | ||
| alcohol | No | true = has an alcohol item, false = has none. | |
| country | No | ISO country code, uppercase. Only these countries have data. | |
| cuisine | No | Cuisine label substring. | |
| service | No | Not reported for Cambodia, Myanmar and ~10% of Indonesia. | |
| minItems | No | Minimum menu items. | |
| minVotes | No | ||
| postcode | No | Postcode prefix. | |
| minRating | No | ||
| sellsItem | No | Menu item name substring. | |
| sortOrder | No | ||
| joinedAfter | No | Oldest menu item created on/after this date (YYYY-MM-DD). | |
| joinedBefore | No | Oldest menu item created before this date (YYYY-MM-DD). | |
| medianPriceMax | No | Median item price, local currency. | |
| medianPriceMin | No | Median item price, local currency. | |
| minBadgedItems | No | Items with a Grab popularity badge (most ordered, most liked, signature dish). | |
| menuUpdatedAfter | No | Newest menu item created on/after this date (YYYY-MM-DD). | |
| minDiscountedRatio | No | Share of items on discount. | |
| minVegetarianRatio | No | Share of items tagged vegetarian. | |
| minWeeklyOpenHours | No | ||
| minAvgDiscountRatio | No | Average price cut on discounted items (0.25 = 25% off). | |
| minHealthTaggedRatio | No | Share of items with a health tag (low carb, high protein, …). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only and closed-world safety, but the description adds substantial behavioral context beyond that: per-country data coverage, menu fetch dates, weakness of dietary flags, substring matching quirks, and return format including distanceKm. This is exactly the kind of extra context that helps an agent set expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Despite its length, the description is front-loaded with purpose and default sort, then organized into scannable sections with bullet points. Every sentence adds practical value for a tool with 29 parameters, and nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (29 params, nested objects, no output schema), the description covers return format, pagination, data recency, and coverage limits. An agent has everything needed to call it correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 76% schema coverage, the description compensates heavily by explaining semantics of location targeting (city vs area vs postcode), cuisine substring matching, sellsItem performance, menu stats filters, and dietary flag limitations. Many parameters receive meaning beyond their schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Search') and resource ('GrabFood restaurants'), and immediately defines default sorting behavior. It distinguishes from sibling Grab_list_areas by directing to it for city lists, and the scope is clearly restaurant search rather than menu item search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides extensive guidance on how to target locations (city vs area vs postcode vs near) and when each filter is effective, including caveats like near only working in Singapore and 8% of Indonesian restaurants. However, it does not explicitly state when to choose this tool over siblings Grab_get_restaurant or Grab_search_menu_items.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
- First observed
Grab_get_restaurant - First observed
Grab_list_areas - First observed
Grab_search_menu_items - First observed
Grab_search_restaurants
Related MCP Connectors
5 lakh+ Indian restaurants: menus with prices, timings, phones and dish search. Free, no API key.
AI food ordering across Canada — 17,000+ restaurants, 89 cities, real UberEats + DoorDash.
Restaurant picks from food creators you trust: ranked guides, reviews and places near you.
Find venues, book tables, rooms and services, buy event tickets and order food delivery.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables AI agents to search Snappfood restaurants and SnappMarket stores across Iran, compare true order costs including packaging and delivery, read menus, minimum orders, ETAs and reviews, and surface live flash deals. All operations are read-only, with no login, basket, ordering or payment access.21878 PyPI33MIT
- AlicenseAqualityCmaintenanceEnables an AI assistant to browse restaurants and menus, manage a cart, reorder past orders, review checkout details, and place food delivery orders, returning a payment link to complete payment.13MIT
- AlicenseBqualityBmaintenanceProvides programmatic access to Grubhub's food delivery platform, enabling restaurant search, menu browsing, cart management, order placement, and delivery tracking through MCP tools.36MIT
- AlicenseAqualityDmaintenanceAI agents can order DoorDash food delivery: search restaurants, browse menus, add items to cart, place orders, and track delivery in real-time.952 npm9MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.