geizhals-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@geizhals-mcpWhat's the current best price for the Sony WH-1000XM5 headphones?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
An MCP server that lets an AI search Geizhals price
comparison data: products, best prices, price history, ratings and categories.
It wraps the Geizhals mobile app's API (api.geizhals.net/gh/v9) and returns the
important fields to the AI.
Highlights
Best price across every shop
Find a product and get its best price, the cheapest shops with shipping and stock, full price range, star ratings and test-review count, aggregated over all Geizhals merchants instead of a single listing.Know when to buy
Pull the full price history and the current price drops (Schnäppchen), sortable by biggest percent off, so a model can answer "is this cheap right now or should I wait".From keyword to category
Search by free text or browse the complete Geizhals category tree (2200+ categories shipped with the server) to drill into exactly the right segment, then compare a shortlist side by side.Price a used listing
match_geizhalsfinds the Geizhals product behind a second-hand ad (with a confidence score), andget_model_price_rangeshows what that model costs new across all its variants. Together they answer "is this used offer a good deal?".
Related MCP server: galaxus-mcp
Setup
Requires Python 3.10+.
pip install -r requirements.txtWith uv you can skip this step: main.py
declares its own dependencies, so uv run main.py installs them on the fly.
Run
python main.pyThe server starts over streamable HTTP and prints where it's listening:
Starting geizhals-mcp server on http://127.0.0.1:8000/mcpPoint your MCP client at that URL. Host, port and path live at the top of
main.py.
For clients that start the server themselves, python main.py --stdio speaks
MCP over stdin/stdout instead. Nothing has to run in the background then.
Add it to Claude (and other MCP clients)
Clients that start their own servers use the stdio mode. Clients that connect
to a URL need python main.py running and take the URL it printed on startup.
Claude Code
One command, no config file. Claude Code starts the server itself:
claude mcp add geizhals -- python /path/to/geizhals-mcp/main.py --stdioOr connect to a server you already started with python main.py:
claude mcp add --transport http geizhals http://127.0.0.1:8000/mcpAdd --scope user to have it in every project instead of only the current one.
claude mcp list shows whether the connection came up, claude mcp remove geizhals takes it out again.
Cursor, Codex, VS Code and other JSON-config clients
Same URL, in the client's MCP config:
{
"mcpServers": {
"geizhals": {
"type": "http",
"url": "http://127.0.0.1:8000/mcp"
}
}
}Claude Desktop
Custom connectors (Settings > Connectors) connect from Anthropic's cloud, so they cannot reach a server running only on your own machine. Two ways around it:
Let Claude Desktop start it over stdio. Open Settings > Developer > Edit
Config, add the geizhals entry to claude_desktop_config.json and restart
Claude Desktop:
{
"mcpServers": {
"geizhals": {
"command": "python",
"args": ["C:\\path\\to\\geizhals-mcp\\main.py", "--stdio"]
}
}
}Use the full path to main.py (forward slashes on macOS/Linux). With uv
installed, "command": "uv" and "args": ["run", "/path/to/geizhals-mcp/main.py", "--stdio"] also takes care of the dependencies.
Or expose the server (cloudflared, ngrok, or run it on a box with a public hostname) and add that HTTPS URL under Settings > Connectors > Add custom connector. That way the tools also work in claude.ai and the mobile apps. Anyone who finds the URL can use the server too, though, so put authentication in front of it.
Every tool is marked read-only, so clients that honour that hint won't ask before each call. In Claude Desktop you can also open Settings > Connectors > geizhals and set the tools' dropdown on the right to Always allow.
Tools
Most tools take three shared parameters: loc is the country site,
"at" (default) or "de"; hloc lists the shop countries to include and
defaults to [loc]; lang ("en" or "de") sets the language of category
names. Results come as compact JSON, and fields without a value are left out.
Search products by keyword, with filters for category and manufacturer, sorting
and paging (rows up to 50). Every hit carries its current best_price,
avg_price, offer_count, currency, cheapest shop, rating_* and an
available flag, so a plain price-or-rating question needs no follow-up call.
Hits with no live offers add alltime_price_min / alltime_price_max /
alltime_last_date, so even discontinued products come with a price, without
a call per hit. The facets list the ten largest categories and manufacturers,
to narrow the search with.
sort takes "" (relevance), "p" (cheapest first) or "-p" (most expensive first);
Geizhals has no newest or rating order for a search. A price sort narrows the
result set as well as ordering it: Geizhals cannot price-order a product that
has no price, so unavailable products leave both results and total.
Full detail of one product: current best price and offer count, name, category,
rating, images, GTIN, offer link, all-time price range and test-review count.
offers lists the cheapest shops with price, cheapest shipping, total, the
shop's own stock text and its rating. A product with no live offers gets its
last_known_price / last_known_date filled in.
Returns a summary of the requested window (window_min/max/avg/change_percent)
and, kept separate, of the product's whole history (alltime_min/max), plus a
[iso_date, price] series that only lists the days the price changed. granularity="day" or "week" give a point
per day or per week instead, and include_series=False leaves the series out.
Average rating, totals, per-star counts and the reviews link.
List the products in a category by its code, with price bounds, paging (rows
up to 50) and sorting: "t" (relevance), "p" / "-p" (price up or down),
"n" (newest listings) or "bew" (best rated). Hits use the same field names
as search_geizhals, and the price_range returned alongside them is the
category's real one (the search facet's is not).
Compare up to ten products side by side, specs included. Properties that don't apply to a product are dropped rather than shown as empty, and the specs are in German because that is all Geizhals has. Discontinued products carry their last known price.
Current price drops: products whose best price just fell, with the percent and
amount off and a link to the product page. Sort by biggest percent drop,
price, latest, popularity or top deals, and filter with
min_discount_percent / max_price. Filters and sorting work over every
current drop (about a thousand), and limit (up to 50) is how many matches come
back. next_offset fetches the next page; the feed is cached for two minutes,
so further pages come back instantly.
What a model costs right now across all its variants (min, median, max
and the five cheapest), e.g. every RTX 5070 rather than one manufacturer's
version. Sibling models (4070 Ti, 4070 Super) are kept out. The result
always comes from one category, because a plain search for a graphics card also
turns up cheaper water blocks and cases and pricier complete PCs. If you don't
pass a category, it is detected and returned as category_code. Up to 300
search hits are considered.
Takes the title of a second-hand ad ("Gigabyte RTX 5070 Windforce OC 12GB NEU
OVP mit Rechnung") and returns the Geizhals products it could be, each with a
0–1 confidence and its current price. Marketplace listings without a category (mostly prebuilt PCs that name
the card they contain) score low, so they don't pass for the card itself. When
the top candidates are too close to separate, or nothing scores convincingly,
a note says so rather than letting a coin-flip look like an answer.
Browse Geizhals' category tree to find the category codes browse_category
takes. Matches English or German names ("graphics cards" and "grafikkarten"
both work). The full tree ships with the server in data/categories.json.
Notes
main.pyis the server and its tools. What they build on lives in thegeizhalspackage:api.pysigns and sends the requests,summaries.pyturns the raw records into results,matching.pymatches ad titles and models, andcategories.pyreads the category tree.data/categories.jsonis a snapshot of Geizhals' category tree (title, title_de, id, children).geizhals/categories.pyloads it forlist_categories, which matches queries against both the English and German names.The badges above read
coverage.jsonfrom thecoveragebranch.scripts/update_coverage.pyrefreshes it from the Geizhals homepage, and a daily GitHub Action commits any change to that branch, so the refresh stays out ofmain's history.Only the Austrian and German sites are offered. On the others (
eu,uk,pl) the endpoints disagree on currency,skrejects every call, and the at/de sites ignore shops from other countries anyway.What all tools share (which tool to start with, what
loc/hloc/langmean,idvsvariant_id) is sent once as the server's instructions instead of being repeated in every tool description.API details are documented in
search_api.md.This uses Geizhals' internal mobile API, not an official one. Be nice to it.
Tests
pip install pytest
pytestThe suite runs offline against canned API responses and goes through a real
MCP client, stdio transport included. GEIZHALS_LIVE=1 pytest adds smoke tests
against the live API. CI runs the offline suite on every push and the live
tests once a day, which is what catches Geizhals rotating its signing secret.
Troubleshooting
403 invalid request_fingerprint in payload — the HMAC secret or
signing scheme in geizhals/api.py (GH_HMAC_SECRET, request_fingerprint,
API_HOST) no longer matches what the live Geizhals app sends. This is
reverse-engineered from the app and hardcoded, so it can drift whenever
Geizhals rotates the secret or changes the fingerprint scheme.
400 Bad Request — Geizhals validates several params against fixed sets
and rejects anything else outright. The two that bite: pagesize must be one
of 1/5/10/30/100/300/1000, and price_history's days must be 31/91/183/365.
The tools snap rows and days to allowed values, so a 400 usually means
another param drifted; the response body names the offending field. Tools
report it as a tool error with a readable message rather than the raw HTTP
error, so the model sees what went wrong instead of an internal URL.
could not answer ... (HTTP 503) — the request was fine but Geizhals did
not answer, even after two retries. That is on their side; try again later.
Disclaimer
This is an independent, unofficial project and is not affiliated with, endorsed by, or connected to Geizhals. "Geizhals" and all related trademarks belong to their respective owners.
It's published for educational and research purposes only. It talks to Geizhals' internal API, which is not meant for public use and may break or change at any time. You are responsible for how you use it: respect Geizhals' Terms of Service, robots rules and applicable law, and don't hammer their servers.
License
MIT LICENSE. Provided "as is", without warranty.
This server cannot be deployed
Maintenance
Related MCP Connectors
Search products, compare prices and discover deals across 6 European markets with your AI assistant.
AI shopping comparison — search 50M+ products, compare prices, find deals
Free, read-only price comparison for products sold in Australia. Search products, browse categories, open a product with every seller's current price (eBay Australia, Amazon, JB Hi-Fi and more), and compare two products head to head. No login or API key. Answers come from Lianex's cached catalogue, so they are fast and never place an order or change anything. Docs: https://lianex.ai/developers
Search ~8.5M products from 2,500+ Central European e-shops. Semantic, keyword, GTIN lookup.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables searching geizhals.de for products and retrieving shop prices and offers to assist with price comparison.2MIT
- AlicenseAqualityCmaintenanceEnables AI assistants to search products and retrieve detailed information from Galaxus and Digitec, including prices, specifications, and price history.54MIT
- AlicenseAqualityFmaintenanceEnables product search and discovery on Galaxus and Digitec, with tools for searching, browsing, comparing, and looking up prices and specifications.71MIT

idealo MCP Serverofficial
AlicenseNot gradedqualityFmaintenanceEnables product search, price comparison, and price history analysis across 6 European marketplaces (DE, AT, GB, FR, IT, ES).21MIT