Canuckeats — Canadian Food Delivery
AI food ordering across Canada — 17,000+ restaurants, 89 cities, real UberEats + DoorDash.
Open source Repository Open in the app JSON README (API)
About
AI food ordering across Canada — 17,000+ restaurants, 89 cities, real UberEats + DoorDash.
Details
- Kind
- MCP servers
- Topic
- No topic detected
- Publisher
- canuckeats
- Origin
- official
- Category
- ferramentas
- Transport
- http
- Version
- 1.0.0
- Stars
- 1
- Last push
- 2026-04-28T01:15:04Z
- Repository state
- ativo
- Added
- 2026-08-29 03:02:33
- Updated
- 2026-08-29 03:02:33
- Origin id
io.github.canuckeats/canuckeats
README
# Canuckeats MCP — AI-Powered Canadian Food Delivery
**Order UberEats and DoorDash in Canada through AI agents.** Canuckeats is a Model Context Protocol (MCP) service that lets AI agents browse menus and place real food delivery orders across 89 Canadian cities — no human in the loop required.
> **Endpoint:** `https://mcp.canuckeats.com/mcp`
> **Registration:** `POST https://mcp.canuckeats.com/register` — free, instant, no email confirmation
> **Protocol:** [MCP 2024-11-05](https://modelcontextprotocol.io/specification/2025-11-05) — Streamable HTTP
> **Coverage:** 17,000+ restaurants · 89 cities · Canada only · UberEats + DoorDash
---
## Why Canuckeats for Agents?
Canadian residents who want AI assistants to handle their food delivery face a gap: UberEats and DoorDash don't offer agent-accessible APIs. Canuckeats bridges that gap. An agent given a task like *"order me sushi for dinner"* can:
1. Find open restaurants near the user's address in their city
2. Browse full menus with prices and modifier options
3. Get a precise cost breakdown before charging anything
4. Place the order and confirm payment in a single tool call
5. Track delivery status and report the ETA back to the user
Every order dispatches through real UberEats or DoorDash accounts — the same food, same drivers, same cities.
---
## Get an API Key — Instant Self-Signup
No waiting, no approval queue. Register your agent and start making calls in under 30 seconds:
```http
POST https://mcp.canuckeats.com/register
Content-Type: application/json
{
"agent_name": "MyFoodAgent",
"email": "you@yourproject.com",
"description": "AI assistant that orders lunch for remote teams"
}
```
**Response:**
```json
{
"api_key": "your-api-key-shown-once",
"key_id": "uuid",
"scopes": ["catalog:read", "orders:write"],
"medusa_customer_id": "cus_...",
"mcp_endpoint": "https://mcp.canuckeats.com/mcp",
"docs": "https://github.com/canuckeats/MCP",
"message": "Registration successful. Keep your API key secure — it is shown only once and cannot be retrieved again."
}
```
**The key is shown once.** Save it immediately. If you lose it, register again with the same email — duplicate email is rejected, so use a unique email per key.
**Registration limits:** Up to 5 registrations per IP per 24 hours. One key per email address. Disposable email addresses are not accepted.
---
## What Cities Are Covered?
All major Canadian cities: **Calgary, Edmonton, Vancouver, Toronto, Ottawa, Montreal, Winnipeg, Hamilton, London, Halifax, Saskatoon, Regina, Kelowna, Victoria, Abbotsford, Barrie, Brampton, Burlington, Burnaby, Coquitlam** and 69 more across **Alberta, British Columbia, Ontario, Manitoba, Saskatchewan, Nova Scotia, New Brunswick** and other provinces.
Use `list_cities` to get the current full list with restaurant counts.
---
## 8 Tools — Full Order Lifecycle
| Tool | Auth | Description |
|------|------|-------------|
| `list_cities` | API key | List all 89 cities with restaurant counts |
| `search_restaurants` | API key | Search by city, cuisine, name, or price range |
| `get_restaurant` | API key | Full restaurant details |
| `get_menu` | API key | Complete menu with sections, prices, and modifier options |
| `validate_order` | API key | Preview exact total — no charge, no order created |
| `create_order` | API key | Create order + Stripe PaymentIntent (no charge yet) |
| `confirm_payment` | API key | Charge card and dispatch order to platform |
| `get_order_status` | API key | Live status, tracking URL, and ETA |
---
## Quickstart: Connect in 60 Seconds
### Python (using `mcp` SDK)
```python
import asyncio, json
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
async with streamablehttp_client(
"https://mcp.canuckeats.com/mcp",
headers={"Authorization": "Bearer YOUR_API_KEY"}
) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
# Find restaurants
result = await session.call_tool("search_restaurants", {
"city_slug": "vancouver-bc",
"query": "sushi",
"limit": 5
})
restaurants = json.loads(result.content[0].text)
print(f"Found {restaurants['total']} sushi spots in Vancouver")
asyncio.run(main())
```
### TypeScript / Node.js
```typescript
import { Client } from "@modelcontextprotocol/sdk/client/index.js"
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"
const client = new Client({ name: "my-agent", version: "1.0" }, { capabilities: {} })
await client.connect(new StreamableHTTPClientTransport(
new URL("https://mcp.canuckeats.com/mcp"),
{ requestInit: { headers: { Authorization: "Bearer YOUR_API_KEY" } } }
))
const result = await client.callTool({ name: "list_cities", arguments: {} })
const cities = JSON.parse(result.content[0].text)
console.log(`${cities.length} cities available`)
```
### Claude Desktop Integration
Add to your Claude Desktop MCP config (`claude_desktop_config.json`):
```json
{
"mcpServers": {
"canuckeats": {
"type": "streamable-http",
"url": "https://mcp.canuckeats.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
Then ask Claude: *"Order me a pepperoni pizza from anywhere in Calgary to 400 4 Ave SW, Calgary AB T2P 0J4."*
---
## Complete Order Flow
```
list_cities → get city slug (e.g. "calgary-ab")
↓
search_restaurants → get restaurant id
↓
get_menu → get menu_item_id + modifier options
↓
validate_order → confirm total (no charge)
↓
create_order → get order_id + stripe_payment_intent_id
↓
confirm_payment → charge pm_... and dispatch
↓
get_order_status (poll) → track until delivered
```
See [docs/examples/order-flow.md](docs/examples/order-flow.md) for a narrated walkthrough with real request/response examples.
---
## Rate Limits
| Endpoint | Limit |
|----------|-------|
| `/register` | 5 registrations per IP per 24 hours |
| All tools (general) | 60 requests / minute per key |
| `create_order`, `confirm_payment` | 10 requests / minute per key |
Response headers `X-RateLimit-Limit` and `X-RateLimit-Remaining` are included on every MCP response.
---
## Key Facts for Agents
- **Canadian addresses only.** Province must be a two-letter code: `AB`, `BC`, `ON`, `QC`, `MB`, `SK`, `NS`, `NB`, `NL`, `PE`, `NT`, `YT`, `NU`.
- **Payment method:** `confirm_payment` accepts a Stripe `pm_*` payment method ID. The agent's operator must provide a valid Stripe payment method that has already been set up with Stripe.
- **Order dispatch is automatic.** After `confirm_payment` succeeds, orders are forwarded to UberEats or DoorDash within 2–5 minutes. Use `get_order_status` to track.
- **Delivery platform is chosen automatically** based on which platform has that restaurant in its catalog.
- **`source_id` on menu items** is used internally — you do not need to reference it directly. Just use `menu_item_id` (the integer `id` field) when calling `create_order`.
- **Modifiers are optional.** If a menu item has required modifiers (e.g. drink size), omitting them may cause the order to fail at the platform level. Check `modifier_groups[].min_selections` to know which are required.
- **Scheduled delivery** is supported via the `scheduled_for` ISO 8601 field on `create_order`. Use ASAP delivery by omitting this field.
---
## Supported Delivery Platforms
| Platform | Coverage |
|----------|----------|
| **UberEats** | All 89 cities |
| **DoorDash** | All 89 cities |
Orders are placed on whichever platform has the requested restaurant. The `source` field on each restaurant (`"ubereats"` or `"doordash"`) tells you which platform will be used.
---
## Canadian Cities — Full List
Alberta · British Columbia · Manitoba · New Brunswick · Newfoundland · Nova Scotia · Ontario · Prince Edward Island · Quebec · Saskatchewan
Use `list_cities` for the live list. Notable cities include:
**Alberta:** Calgary, Edmonton, Red Deer, Lethbridge, Airdrie, Medicine Hat, Grande Prairie, Fort McMurray
**BC:** Vancouver, Surrey, Burnaby, Richmond, Kelowna, Abbotsford, Victoria, Coquitlam, Langley
**Ontario:** Toronto, Ottawa, Hamilton, London, Brampton, Mississauga, Barrie, Windsor, Kitchener, Ajax, Aurora
**Quebec:** Montreal (selected areas)
**Prairie & Atlantic:** Saskatoon, Regina, Winnipeg, Halifax, Moncton, Fredericton
---
## API Reference
- [Full tool schemas with TypeScript types](docs/tools.md)
- [Quick start guide with code samples](docs/quickstart.md)
- [End-to-end order walkthrough](docs/examples/order-flow.md)
- [Machine-readable tools manifest](tools.json)
---
## Support
- **Issues / questions:** Open a GitHub issue in this repo
- **API key lost:** Re-register with a different email, or email hello@canuckeats.com
- **Order issues:** Email hello@canuckeats.com with your `order_id`
- **Website:** [canuckeats.com](https://canuckeats.com)