loading…
Search for a command to run...
loading…
A thin MCP server that exposes Wolt's public consumer endpoints to AI agents, enabling discovery of nearby venues and fetching their menus with live prices and
A thin MCP server that exposes Wolt's public consumer endpoints to AI agents, enabling discovery of nearby venues and fetching their menus with live prices and deal signals.
A thin Model Context Protocol server that exposes Wolt's public consumer endpoints to AI agents. Point it anywhere Wolt operates — the default coordinates are Tallinn, Estonia, but you can override per-call or via env vars.
Two tools, no magic:
list_nearby — venues near a lat/lon, filtered by substring, rating, open/closed status.get_menu — full menu for a venue by slug, with prices, 30-day lows, and category structure.It's read-only on purpose. Wolt's ordering API is gated behind merchant credentials; this server intentionally doesn't try to place orders.
You want an AI assistant (Claude Code, Cursor, Continue, Zed, or your own Agent SDK app) that can:
ERIPAKKUMISED (Estonian), SPECIAL OFFERS, or KUUPAKKUMINE (monthly offer), plus lowest_price (the 30-day low used for EU compliance display).Wolt's consumer-api.wolt.com is global; this server has no country hardcoding. Change WOLT_DEFAULT_LAT / WOLT_DEFAULT_LON (or pass lat/lon per call) to work anywhere Wolt delivers — Finland, Germany, Czechia, Estonia, Israel, Greece, Japan, and more. Verified live against Tallinn (59.4370, 24.7536); other regions should work with the same endpoints.
git clone https://github.com/fogside/wolt-mcp
cd wolt-mcp
python3 -m venv .venv
.venv/bin/pip install -e .
Then register it with any MCP-capable client. For Claude Code, drop this at the project root:
{
"mcpServers": {
"wolt": {
"command": "./.venv/bin/wolt-mcp",
"args": [],
"env": {
"WOLT_DEFAULT_LAT": "59.4370",
"WOLT_DEFAULT_LON": "24.7536",
"WOLT_LANGUAGE": "en"
}
}
}
}
For Claude Desktop, add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the equivalent on Linux/Windows:
{
"mcpServers": {
"wolt": {
"command": "/absolute/path/to/wolt-mcp/.venv/bin/wolt-mcp",
"env": { "WOLT_DEFAULT_LAT": "59.4370", "WOLT_DEFAULT_LON": "24.7536" }
}
}
}
Any other MCP client that supports stdio transport works the same way — run wolt-mcp as the command.
list_nearby| Param | Type | Default | Notes |
|---|---|---|---|
lat |
float | $WOLT_DEFAULT_LAT |
|
lon |
float | $WOLT_DEFAULT_LON |
|
radius |
int (m) | 3000 |
200–20000 |
query |
str? | None |
Substring match against name + tags |
only_open |
bool | False |
|
min_rating |
float? | None |
0–10 scale |
max_results |
int | 30 |
|
language |
str | $WOLT_LANGUAGE or en |
Returns a list of dicts: name, slug, id, online, rating, rating_volume, eta_minutes, price_range, tags, short_description, address.
get_menu| Param | Type | Default | Notes |
|---|---|---|---|
slug |
str | — | From list_nearby, e.g. vapiano-foorum |
language |
str | en |
|
include_disabled |
bool | False |
Returns { slug, assortment_id, primary_language, selected_language, available_languages, categories: [{ id, name, slug, description, items: [...] }], uncategorised_items, item_count }. Each item has id, name, description, price, original_price, lowest_price, enabled, tags.
Prices are integers in minor units. 2390 = €23.90. Currency is not on items — infer from venue country.
| Var | Default | Purpose |
|---|---|---|
WOLT_DEFAULT_LAT |
59.4370 |
Tallinn center |
WOLT_DEFAULT_LON |
24.7536 |
|
WOLT_LANGUAGE |
en |
Sent as Accept-Language |
WOLT_MCP_LOG |
WARNING |
Python logging level |
"Find the top five sushi places near me that are open right now." →
list_nearby(query="sushi", only_open=True, min_rating=9, max_results=5)"Pull Vapiano Foorum's menu and tell me what's vegetarian." →
get_menu(slug="vapiano-foorum")then the LLM filters by description."Compare prices for pad thai between these three Thai venues." → one
list_nearby+ threeget_menucalls."Summarise current deals at my favorite café." →
get_menu— surface items in categories named likeERIPAKKUMISED/SPECIAL OFFERS/KUUPAKKUMINE, or with⭐in the name.
Wolt venues in practice use category membership as their deal signal much more often than original_price. A typical Estonian cafe will have a category named ERIPAKKUMISED ("special offers") or KUUPAKKUMINE ("monthly offer") containing the discounted items, while original_price on those items stays null.
When prompting your agent, don't rely on a price-diff — ask it to inspect category names and item names (⭐ prefixes are common) as the first-class signal. lowest_price is useful for longer-range price-tracking: it's the 30-day low that Wolt surfaces for EU price-transparency compliance.
assortment endpoint often returns the venue's primary language (e.g. Estonian) even when en is requested — most venues don't publish auto-translated content. You'll see the actual selected language in the response's selected_language field.This project hits Wolt's public, unauthenticated consumer endpoints — the same ones wolt.com's web app calls. Automated access at scale is contrary to Wolt's Terms of Service. Use this for personal agent assistance, experimentation, or research. Don't build a scraper at scale with it.
jlowin/fastmcp project..venv/bin/pip install -e ".[dev]" # once dev extras are defined
.venv/bin/wolt-mcp # runs the server on stdio — connect a client
Contributions welcome — especially venue-specific deal-detection heuristics for cities outside Estonia, or a venue_dynamic(slug) tool if you can find a working endpoint.
MIT.
Run in your terminal:
claude mcp add wolt-mcp -- npx Security
Low riskAutomated heuristic from public metadata — not a security guarantee.