Skip to main content
Glama
README.md
# MealOS

Cross-server Swiggy meal intelligence — plan, order, and manage meals across Food, Instamart, and Dineout from a single Claude Desktop conversation.

**Verified working:** placed a live Swiggy order entirely through Claude Desktop chat.

## What it does

MealOS is a local MCP server that gives Claude Desktop a unified meal planning brain. Instead of juggling three separate Swiggy apps, you tell Claude what you want and it:

- Plans 21 meals (breakfast/lunch/dinner × 7 days) routing each to the right Swiggy service
- **Cook at home** → builds an Instamart grocery cart, skipping what's already in your fridge
- **Order in** → finds a restaurant on Swiggy Food, builds a delivery cart, places the order
- **Dine out** → finds a free table reservation on Dineout for Friday/Saturday evenings
- Tracks your weekly budget split across all three modes
- Always asks for confirmation before placing any order or booking

## Architecture

```
Claude Desktop (orchestrator)
        │
        └── mealos MCP server (local stdio)
                ├── State tools      → profile, fridge, weekly plan (~/.mealos/state.json)
                ├── Food proxy       → 14 tools via https://mcp.swiggy.com/food
                ├── Instamart proxy  → 13 tools via https://mcp.swiggy.com/im
                └── Dineout proxy    → 8 tools  via https://mcp.swiggy.com/dineout
```

Claude Desktop connects to a single local MCP server. That server proxies all 35 Swiggy tools internally using a stored OAuth token — no remote MCP config needed.

## Live Order Flow (what actually happens)

```
You: "Order chicken biryani for dinner"

Claude → mealos: get_addresses          → your Hyderabad address
Claude → mealos: search_restaurants     → finds open biryani places near you
Claude → mealos: get_restaurant_menu    → browses Chaitanya Food Court
Claude → mealos: search_menu            → finds Chicken Dum Biryani, shows sizes
You: "Family size"
Claude → mealos: update_food_cart       → adds item (menu_item_id + quantity)
Claude → mealos: get_food_cart          → shows total, delivery fee, coupon applied
Claude: "Cart total ₹426. Place order?"
You: "Yes"
Claude → mealos: place_food_order       → order placed ✅
                                        → confirmation SMS on your phone
```

Total time: ~2 minutes. No app switching.

> **Note on cart visibility:** The MCP API uses a separate device session (`deviceId: im-mcp-server`) from the Swiggy app. Cart won't show in the app, but placed orders appear in your order history.

## MealOS State Tools

| Tool | Description |
|------|-------------|
| `mealos_get_context` | Full planning context: profile + fridge + plan + constraints. Call at session start. |
| `mealos_get_profile` / `mealos_set_profile` | Read/write preferences: budget, dietary, cook/dine days, location |
| `mealos_get_fridge` / `mealos_update_fridge` | Read/write pantry inventory — Instamart skips items already stocked |
| `mealos_get_plan` / `mealos_save_plan` | Read/write the current weekly plan |
| `mealos_update_meal_status` | Mark a meal as confirmed / ordered / skipped |

## Swiggy Tools (proxied)

All 35 tools accessible through the single mealos server:

**Food (14):** `get_addresses`, `search_restaurants`, `get_restaurant_menu`, `search_menu`, `update_food_cart`, `get_food_cart`, `flush_food_cart`, `fetch_food_coupons`, `apply_food_coupon`, `place_food_order`, `get_food_orders`, `get_food_order_details`, `track_food_order`, `report_error`

**Instamart (13):** `search_products`, `your_go_to_items`, `update_cart`, `get_cart`, `clear_cart`, `checkout`, `get_orders`, `get_order_details`, `track_order`, `create_address`, `delete_address`

**Dineout (8):** `get_saved_locations`, `search_restaurants_dineout`, `get_restaurant_details`, `get_available_slots`, `book_table`, `get_booking_status`

## Built-in Prompts

Use these from the Claude Desktop prompt picker (`/` in chat):

- **`plan_week`** — Generate a full weekly meal plan across all three Swiggy services
- **`quick_order`** — Place a food delivery order right now
- **`restock_groceries`** — Restock the fridge via Instamart
- **`book_dinner`** — Find and book a free restaurant table for dinner

## Setup

### Prerequisites
- [Claude Desktop](https://claude.ai/download)
- Node.js 18+
- A Swiggy account with Builders Club API access

### 1. Clone and install

```bash
git clone https://github.com/naga-pavan12/mealOS.git
cd mealOS
npm install
```

### 2. Authenticate with Swiggy

```bash
npx tsx src/auth-cli.ts
```

This opens your browser for Swiggy OAuth login. Token saves to `~/.mealos/auth.json`. Only needed once — token auto-refreshes.

### 3. Build and deploy the MCP server

```bash
npm run build
mkdir -p ~/.mealos
cp dist/mcp-server.mjs ~/.mealos/mcp-server.mjs
```

> **Why `~/.mealos/`?** Claude Desktop on macOS sandboxes spawned processes and blocks file reads from `~/Downloads`. The bundle must live outside Downloads.

### 4. Configure Claude Desktop

Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "mealos": {
      "command": "/opt/homebrew/bin/node",
      "args": ["/Users/YOUR_USERNAME/.mealos/mcp-server.mjs"]
    }
  }
}
```

### 5. Restart Claude Desktop

mealos should appear as connected under Settings → Developer. You'll see 39 tools available.

### 6. Set up your profile (first time)

Tell Claude:
> "Set up my MealOS profile. Budget ₹3000/week, non-veg, household of 1, cook on Mon/Wed/Sat, dine out Fri/Sat. I'm in [your city]."

Then add your fridge:
> "Update my fridge: I have 500g chicken, 1kg rice, 4 eggs, some garlic."

## State storage

All state is stored locally — no cloud sync, no external database.

```
~/.mealos/
├── mcp-server.mjs      ← compiled bundle (from dist/)
├── state.json          ← profile, fridge inventory, weekly plan
├── auth.json           ← Swiggy OAuth token (chmod 0600)
└── registration.json   ← OAuth client ID
```

## Swiggy Constraints

Key limits baked into the planning rules:

| Constraint | Limit |
|------------|-------|
| Cart cap | ₹1000 per order (Food + Instamart) |
| Instamart minimum | ₹99 |
| Payment method | COD only (Food, v1) |
| Dineout bookings | Free only (`isFree=true`, `bookingPrice=0`) |
| Confirmation | Required before every order and booking |
| Order retry | Not idempotent — check order history before retrying |

## Development

```bash
npm run build      # bundle src/mcp-server.ts → dist/mcp-server.mjs
npm run typecheck  # type-check without emitting
npx tsx src/auth-cli.ts  # re-authenticate with Swiggy
```

After any code change: `npm run build` → `cp dist/mcp-server.mjs ~/.mealos/` → restart Claude Desktop.