get_store_menu
Retrieve a DoorDash store's complete menu including all items and their prices using the store ID. This tool provides structured menu data for browsing or integration purposes.
Instructions
Get a store's full menu with items and prices
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| storeId | Yes | Store ID from search results | |
| menuId | No | Menu ID (optional) |
Implementation Reference
- mcp-server.js:80-136 (handler)The handler function for 'get_store_menu' tool. Calls GraphQL API to fetch store menu data, processes the response to extract store information (name, rating, delivery time, fees, promos) and menu categories with items (prices, descriptions, badges, deals), then returns formatted JSON output.
async ({ storeId, menuId }) => { const result = await graphql("storepageFeed", queries.STORE_PAGE_FEED, { storeId, menuId, fulfillmentType: "Delivery", }); const feed = result?.data?.storepageFeed; const header = feed?.storeHeader; const promos = (header?.storeTagsList || []) .filter((t) => t.type === "PROMOTION" || t.type === "OFFER" || (t.custom && t.custom.includes("promo"))) .map((t) => t.name); const store = header ? { id: header.id, name: header.name, description: header.description, priceRange: header.priceRangeDisplayString, rating: header.ratings?.averageRating, numRatings: header.ratings?.numRatingsDisplayString, deliveryTime: header.deliveryTimeLayout?.title, deliveryFee: header.deliveryFeeLayout?.displayDeliveryFee, pickupTime: header.pickupTimeLayout?.title, isDashpass: header.isDashpassPartner, promos: promos.length > 0 ? promos : undefined, } : null; const categories = (feed?.itemLists || []).map((list) => ({ id: list.id, name: list.name, items: (list.items || []).map((item) => { const badges = (item.badges || []).filter((b) => b.text).map((b) => b.text); const deal = item.strikethroughPrice && item.strikethroughPrice > 0 ? { originalPrice: `$${(item.strikethroughPrice / 100).toFixed(2)}` } : undefined; return { id: item.id, name: item.name, description: item.description, price: item.price, priceDisplay: item.displayPrice || (item.price ? `$${(item.price / 100).toFixed(2)}` : null), deal, badges: badges.length > 0 ? badges : undefined, tags: (item.itemTagsList || []).map((t) => t.localizedName), }; }), })); return { content: [{ type: "text", text: JSON.stringify({ store, categories }, null, 2) }], }; } ); - mcp-server.js:76-79 (schema)Input schema definition for 'get_store_menu' tool using Zod. Defines storeId as required string parameter and menuId as optional string parameter, with descriptive metadata.
{ storeId: z.string().describe("Store ID from search results"), menuId: z.string().optional().describe("Menu ID (optional)"), }, - mcp-server.js:73-136 (registration)Registration of the 'get_store_menu' tool with the MCP server. Includes tool name, description, input schema, and the handler function that implements the tool logic.
server.tool( "get_store_menu", "Get a store's full menu with items and prices", { storeId: z.string().describe("Store ID from search results"), menuId: z.string().optional().describe("Menu ID (optional)"), }, async ({ storeId, menuId }) => { const result = await graphql("storepageFeed", queries.STORE_PAGE_FEED, { storeId, menuId, fulfillmentType: "Delivery", }); const feed = result?.data?.storepageFeed; const header = feed?.storeHeader; const promos = (header?.storeTagsList || []) .filter((t) => t.type === "PROMOTION" || t.type === "OFFER" || (t.custom && t.custom.includes("promo"))) .map((t) => t.name); const store = header ? { id: header.id, name: header.name, description: header.description, priceRange: header.priceRangeDisplayString, rating: header.ratings?.averageRating, numRatings: header.ratings?.numRatingsDisplayString, deliveryTime: header.deliveryTimeLayout?.title, deliveryFee: header.deliveryFeeLayout?.displayDeliveryFee, pickupTime: header.pickupTimeLayout?.title, isDashpass: header.isDashpassPartner, promos: promos.length > 0 ? promos : undefined, } : null; const categories = (feed?.itemLists || []).map((list) => ({ id: list.id, name: list.name, items: (list.items || []).map((item) => { const badges = (item.badges || []).filter((b) => b.text).map((b) => b.text); const deal = item.strikethroughPrice && item.strikethroughPrice > 0 ? { originalPrice: `$${(item.strikethroughPrice / 100).toFixed(2)}` } : undefined; return { id: item.id, name: item.name, description: item.description, price: item.price, priceDisplay: item.displayPrice || (item.price ? `$${(item.price / 100).toFixed(2)}` : null), deal, badges: badges.length > 0 ? badges : undefined, tags: (item.itemTagsList || []).map((t) => t.localizedName), }; }), })); return { content: [{ type: "text", text: JSON.stringify({ store, categories }, null, 2) }], }; } ); - src/browser.js:77-101 (helper)GraphQL helper function that executes API calls to DoorDash. Used by 'get_store_menu' handler to make authenticated requests to the DoorDash GraphQL endpoint with operation name, query, and variables.
async function graphql(operationName, query, variables = {}) { const page = await ensureOnDoordash(); const result = await page.evaluate( async ({ operationName, query, variables }) => { const res = await fetch( `/graphql/${operationName}?operation=${operationName}`, { method: "POST", headers: { "content-type": "application/json" }, credentials: "include", body: JSON.stringify({ operationName, variables, query }), } ); return { status: res.status, body: await res.json() }; }, { operationName, query, variables } ); if (result.status !== 200) { throw new Error(`GraphQL ${operationName} failed: ${result.status}`); } return result.body; } - src/queries.js:36-62 (schema)GraphQL query definition (STORE_PAGE_FEED) used by 'get_store_menu' tool. Defines the query structure for fetching store header data (name, rating, delivery info, promos) and item lists with menu items (prices, descriptions, badges, tags).
const STORE_PAGE_FEED = `query storepageFeed($storeId: ID!, $menuId: ID, $fulfillmentType: FulfillmentType, $cursor: String) { storepageFeed(storeId: $storeId, menuId: $menuId, fulfillmentType: $fulfillmentType, cursor: $cursor) { storeHeader { id name description priceRange priceRangeDisplayString offersDelivery offersPickup isDashpassPartner address { displayAddress lat lng } deliveryFeeLayout { title displayDeliveryFee } deliveryTimeLayout { title subtitle } pickupTimeLayout { title } ratings { numRatingsDisplayString averageRating } storeTagsList { type name custom } status { delivery { isAvailable minutes } pickup { isAvailable minutes } } } itemLists { id name description items { id name description price imageUrl displayPrice strikethroughPrice nextCursor itemTagsList { tagType localizedName } badges { text type isDashpass placement backgroundColor } } } } }`;