Skip to main content

Unofficial MCP server for Yandex Lavka: search, cart, and place grocery orders from an AI assistant.

Project description

yandex-lavka-mcp

PyPI Python License: MIT MCP

An MCP server that lets an AI assistant order groceries from Yandex Lavka — search products, build a cart, and place a real order — with an explicit human confirmation before any money is charged.

[!WARNING] Unofficial. Yandex Lavka has no public API. This project talks to the same private web API that lavka.yandex.ru uses, authenticated with your own Yandex session cookies. It automates your own account, for your own shopping.

  • Not affiliated with or endorsed by Yandex. Using it may violate Yandex's Terms of Service, and the private API can change or be blocked at any time.
  • confirm_order spends real money on your card. Use at your own risk.
  • Provided as is, without warranty (see LICENSE).

What it does

Tool Charges? What it does
lavka_status Is the session + location set up?
list_addresses Your saved Lavka addresses, by name.
use_address Switch delivery to a saved address by name.
set_delivery_address Set delivery to any address by text (any city).
set_location Set delivery point by raw lat/lon.
search_products Search the catalog at the current location.
get_product Product detail.
view_cart Show cart + total.
add_to_cart Add an item.
update_cart_item Set exact quantity (0 removes).
clear_cart Empty the cart.
checkout_preview no Full summary: items, subtotal, discount, delivery, ETA, payment, total.
confirm_order YES Places the order and charges the on-file card.
cancel_order Cancel an order by id.
active_orders Currently tracked orders with status/ETA.

Money safety. Placing an order is a deliberate two-step flow: checkout_preview returns the full summary and charges nothing; confirm_order(confirmed_total) refuses unless a preview was just run and you pass back the exact total it showed. Change the cart and the preview is invalidated — you must preview again.

3-D Secure. confirm_order submits the order and charges the on-file card, then polls payment status. If your bank requires 3-D Secure, payment_status comes back wait_user_action and a redirect_url is returned — open it to finish paying (a headless charge cannot complete 3DS). cancel_order(order_id) cancels.

Multiple locations / cities. Catalog, prices and cart are location-scoped. use_address("Дача") switches to a saved address; set_delivery_address("Казань, улица Баумана, 1", flat="12") works for any address in any city (it geocodes via Lavka's own address search).

How it's built

  • Python 3.12+ · FastMCP · httpx.
  • client.py — the async API client (session auth, CSRF, request building, trims huge payloads).
  • endpoints.py — every API path in one place (overridable from config, no code change).
  • server.py — the MCP tools the assistant sees.

The API sits under https://lavka.yandex.ru/api/v1/providers/* (plus /api/v1/orders/submit for placing orders). Requests need the CSRF token from the homepage HTML plus X-Lavka-Web-* headers — the client handles this.

Setup

1. Install

uv venv && uv pip install -e .

2. Provide your Yandex session (one time)

Log into Lavka in your browser first, then get the session cookies into ~/.config/yandex-lavka-mcp/config.json.

macOS — pull cookies straight from Chrome (one Keychain prompt → Allow):

uv pip install -e '.[browser]'
python scripts/extract_chrome_cookies.py          # auto-detects your profile

Any OS — paste the Cookie header from DevTools (Network → any lavka.yandex.ru request → Request Headers → Cookie):

python scripts/import_cookies.py --header "Session_id=...; yandexuid=...; L=..."

Session cookies expire — re-run when calls start returning "session expired".

3. Set a delivery location

Copy config.example.json to ~/.config/yandex-lavka-mcp/config.json and edit, or set it from the assistant with use_address / set_delivery_address. The catalog only works once a location is set. Smoke-test:

python scripts/smoke.py "молоко"

4. Register with your assistant

Claude Code:

claude mcp add yandex-lavka -- uv run --directory /path/to/yandex-lavka-mcp yandex-lavka-mcp

Claude Desktop (mcpServers):

{
  "yandex-lavka": {
    "command": "uv",
    "args": ["run", "--directory", "/path/to/yandex-lavka-mcp", "yandex-lavka-mcp"]
  }
}

Remote deploy (order from your phone)

By default the server speaks stdio (local clients). Set YANDEX_LAVKA_MCP_TRANSPORT=streamable-http to expose it over HTTP so a hosted instance can back a claude.ai custom connector (phone / web).

A prebuilt Dockerfile is included. Secrets are injected at runtime — never baked into the image:

docker build -t yandex-lavka-mcp .
docker run -p 8000:8000 \
  -e YANDEX_LAVKA_MCP_CONFIG_JSON="$(cat ~/.config/yandex-lavka-mcp/config.json)" \
  yandex-lavka-mcp

Environment variables

Var Purpose
YANDEX_LAVKA_MCP_TRANSPORT stdio (default) or streamable-http.
YANDEX_LAVKA_MCP_HOST / _PORT Bind address for HTTP (default 0.0.0.0:8000 in Docker).
YANDEX_LAVKA_MCP_CONFIG_JSON The whole config.json as one secret (instead of a file).

Authentication (any OIDC provider)

A public endpoint spends real money, so protect it. claude.ai's custom connector UI only supports OAuth (no static bearer / custom header — that works only in Claude Code/Desktop). This server is a provider-agnostic OAuth 2.1 resource server: point it at any OpenID-Connect provider (Zitadel, Keycloak, Auth0, Google, …) and it validates JWT access tokens against that provider's JWKS and advertises it via OAuth protected-resource metadata.

Enable it by installing the server extra (pip install '.[server]', already in the Docker image) and setting:

Var Purpose
YANDEX_LAVKA_MCP_OAUTH_ISSUER Your provider's issuer URL (enables OAuth).
YANDEX_LAVKA_MCP_SERVER_URL Public URL of this MCP server (the resource).
YANDEX_LAVKA_MCP_OAUTH_AUDIENCE Expected token audience (optional but recommended).
YANDEX_LAVKA_MCP_OAUTH_SCOPES Space-separated required scopes (optional).
YANDEX_LAVKA_MCP_OAUTH_SUBJECTS Allow-list of token subs that may call the server (optional; strongest lock — every request spends your Lavka session).
YANDEX_LAVKA_MCP_OAUTH_JWKS_URL Override JWKS URL (optional; else discovered).

A network-exposed HTTP transport refuses to start unless OAuth is configured (it spends real money). Set YANDEX_LAVKA_MCP_ALLOW_INSECURE=1 only if you front it with your own auth. Leaving OAuth unset is allowed for loopback/local use.

Session cookies expire; when calls start failing, re-capture them and update the YANDEX_LAVKA_MCP_CONFIG_JSON secret. There is no headless Yandex login.

Develop

uv pip install -e ".[dev]"
pytest

One account = one cart

Lavka keeps a single server-side cart per account, guarded by an optimistic cartVersion. This server serializes its own cart writes and retries on version conflicts, so parallel tool calls in one session are safe. But don't drive the same Yandex account from two places at once (e.g. this server and a second MCP session, and the Lavka app): they all write the one shared cart, and you'll see items from the other writer appear in yours. Use a single client at a time.

Security & privacy

  • Cookies and address live only in ~/.config/yandex-lavka-mcp/config.json (chmod 600), git-ignored. Never commit them.
  • The server never adds payment methods or changes account settings.
  • Ordering always requires an explicit confirmed total.

License

MIT. Unofficial project, not affiliated with Yandex.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

yandex_lavka_mcp-0.1.1.tar.gz (74.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

yandex_lavka_mcp-0.1.1-py3-none-any.whl (28.9 kB view details)

Uploaded Python 3

File details

Details for the file yandex_lavka_mcp-0.1.1.tar.gz.

File metadata

  • Download URL: yandex_lavka_mcp-0.1.1.tar.gz
  • Upload date:
  • Size: 74.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for yandex_lavka_mcp-0.1.1.tar.gz
Algorithm Hash digest
SHA256 23184d28c746744d45d4b0d2c9a3ba05d1a975fdf488ac2a6d7d9fdbad9aebfc
MD5 50743b5a9dd8d9dbcc58bbddf93268cf
BLAKE2b-256 a93df12e6bd8902f354880d2471965a3bf90395e3297c584383ee6c96aa62575

See more details on using hashes here.

File details

Details for the file yandex_lavka_mcp-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: yandex_lavka_mcp-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 28.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for yandex_lavka_mcp-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 05075e06aaa00e169cee82699f5d72e7f6254f9f2828ed506077f170feca0d74
MD5 cde65a79ed5678ba40fa03011d3a1030
BLAKE2b-256 a811e4c4e6f68b4d9695a8077d5e789cd19f3ad8a4da2e7a93738bc0c0faa1a8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page