blinkit-mcp
by yniks
README.md
# blinkit-mcp
An **API-only** [MCP](https://modelcontextprotocol.io) server for [Blinkit](https://blinkit.com)
(Indian quick-commerce). Every runtime call is a plain HTTPS request to `blinkit.com` — **no browser
automation in the happy path**. A browser is used only once, during research, to discover endpoints;
see [`RESEARCH.md`](./RESEARCH.md).
## How it works (the important bits)
- **Cloudflare TLS fingerprinting** blocks ordinary HTTP clients (curl, Node `fetch` → 403). We use
[`impit`](https://www.npmjs.com/package/impit) to impersonate Chrome's TLS handshake, so requests
pass with no browser and no cookie/challenge. This is what makes API-only possible.
- **Bootstrap:** `GET /v2/accounts/auth_key/` with a fixed `req_key` constant → device `auth_key`
(no login). Sent on every call.
- **Login is headless OTP:** `send_otp(phone)` → `verify_otp(phone, code)` returns an
`access_token` we persist. No browser ever involved.
- **Server-driven UI** responses are parsed defensively into clean product/order objects.
## Setup
```bash
pnpm install
pnpm build
```
Add to your MCP client (e.g. Claude Code `mcp` config):
```json
{
"mcpServers": {
"blinkit": { "command": "node", "args": ["/path/to/blinkit-mcp/dist/index.js"] }
}
}
```
State is stored in `~/.blinkit-mcp/`:
- `session.json` — device id, auth_key, **access_token** (secret), location, store. chmod 600.
- `staples.json` — your reorder catalog + scorer weights.
- `cart.json` — the current working cart.
## Tools
**Auth/login** — `blinkit_login_status`, `blinkit_send_otp`, `blinkit_verify_otp`, `blinkit_logout`
**Location** — `blinkit_set_location`, `blinkit_check_serviceability`
**Discovery** — `blinkit_search`, `blinkit_autosuggest`, `blinkit_pick_best`, `blinkit_recommendations`, `blinkit_home_feed`
**Cart** — `blinkit_add_to_cart`, `blinkit_remove_from_cart`, `blinkit_view_cart`, `blinkit_clear_cart`
**Reorder** — `blinkit_quick_reorder`, `blinkit_list_staples`, `blinkit_set_staple`
**Checkout/pay** — `blinkit_get_addresses`, `blinkit_checkout`, `blinkit_prepare_order`, `blinkit_pay_upi`, `blinkit_payment_status`
**Orders** — `blinkit_order_count`, `blinkit_order_history`
### Typical flow (fully headless; only PhonePe approval is manual)
```
blinkit_set_location { lat: 28.5653836, lon: 77.38265 } # once, persists
blinkit_send_otp { phone: "9XXXXXXXXX" }
blinkit_verify_otp { phone: "9XXXXXXXXX", code: "1234" } # stores access_token + phone
blinkit_pick_best { query: "milk", brands:["Amul"], attrs:["full cream"] } # → product
blinkit_get_addresses # → address_id
blinkit_checkout { items: [ <chosen> ], address_id } # → server cart_id (creates+binds+validates)
blinkit_pay_upi { cart_id, method:"collect", vpa:"name@ybl", wait:true }
# → pushes a UPI collect to PhonePe; streams status via notifications; you approve on your phone
```
### Payment status & notifications
- **`blinkit_pay_upi`** initiates UPI payment (`method:"qr"` returns a `upi://pay` intent link;
`method:"collect"` + `vpa` pushes a collect request to your UPI app). With `wait:true` it polls
`verifyPaymentStatus` until terminal and returns `final_status`.
- **`blinkit_payment_status`** checks the last (or a given) in-flight payment on demand — returns
`pending` / `success` / `failed`.
- The server declares the MCP **`logging`** capability and emits `notifications/message` during the
wait ("waiting for approval", "✅ approved", "❌ failed") — surfaced live by Claude Code.
> Payment is delegated to Zomato **zpaykit**; the human step is approving the UPI request in PhonePe.
> See `RESEARCH.md §8–9` for the full captured flow.
## Notes / limits
- Unofficial, reverse-engineered API — no stability guarantees; header/version constants may need
bumping. Respect Blinkit's ToS and rate limits; intended for personal automation.
- `auth_key` / `req_key` constants are overridable via `BLINKIT_REQ_KEY` if Blinkit rotates them.
- Not affiliated with or endorsed by Blinkit/Zomato. Use at your own risk.
## License
MIT — see [LICENSE](./LICENSE).
TDQS
A3.6/5.0
Scored across 25 tools
Disambiguation5/5
Each tool targets a distinct action or resource (e.g., add_to_cart vs. remove_from_cart, search vs. pick_best). There is minimal overlap, and descriptions clearly differentiate similar tools.
Naming Consistency5/5
All tools follow a consistent 'blinkit_verb_noun' pattern in snake_case, making the tool surface predictable and easy to navigate.
Tool Count4/5
With 25 tools, the set is slightly larger than the ideal range but justifiable for a full-featured e-commerce MCP server covering login, location, cart, search, ordering, and payment.
Completeness4/5
The surface covers most lifecycle stages (login, search, cart, checkout, payment, staples), but lacks explicit order cancellation or address update during checkout, which are minor gaps.
Maintenance
ActivityStale
ResponsivenessNo issues