Product availability and prices at German DIY stores (OBI, Bauhaus, toom, Hornbach…) by postcode
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Searches watch.diy's index of DIY and garden products at German retailers (OBI, Bauhaus, toom, Hornbach, hagebau, Globus and more) by product name, EAN or manufacturer part number (MPN), and returns up to `limit` (1-5, default 3) products, best match first. Per product: name, brand, its EANs and per retailer the retailer's product name, its product page url and price with priceAsOf (when the price was read; a price older than 35 days is returned as null with priceNote). Only products the retailers sell themselves and still list online; store availability is not part of this answer: use where_to_buy_nearby with an EAN from here and a German postcode. Also returns match (ean, identifier, hybrid or text: how the query was answered) and a notice. When nothing matches, products is empty and message says what the index covers. Limits: public lookups are limited per client. Errors: invalid_request (names the field and the reason), quota_exceeded (with the minutes until it can be tried again), public_unavailable.
Product name or description (any language, typos tolerated), an EAN (8 or 13 digits) or a manufacturer part number (MPN)
Products to return, 1-5 (default 3)
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http diy-store-finder https://mcp.watch.diy/public/mcp
Searches watch.diy's index of DIY and garden products at German retailers (OBI, Bauhaus, toom, Hornbach, hagebau, Globus and more) by product name, EAN or manufacturer part number (MPN), and returns up to `limit` (1-5, default 3) products, best match first. Per product: name, brand, its EANs and per retailer the retailer's product name, its product page url and price with priceAsOf (when the price was read; a price older than 35 days is returned as null with priceNote). Only products the retailers sell themselves and still list online; store availability is not part of this answer: use where_to_buy_nearby with an EAN from here and a German postcode. Also returns match (ean, identifier, hybrid or text: how the query was answered) and a notice. When nothing matches, products is empty and message says what the index covers. Limits: public lookups are limited per client. Errors: invalid_request (names the field and the reason), quota_exceeded (with the minutes until it can be tried again), public_unavailable.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Products to return, 1-5 (default 3) |
| query* | string | Product name or description (any language, typos tolerated), an EAN (8 or 13 digits) or a manufacturer part number (MPN) |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"query"
],
"properties": {
"limit": {
"type": "integer",
"default": 3,
"maximum": 5,
"minimum": 1,
"description": "Products to return, 1-5 (default 3)"
},
"query": {
"type": "string",
"maxLength": 200,
"minLength": 2,
"description": "Product name or description (any language, typos tolerated), an EAN (8 or 13 digits) or a manufacturer part number (MPN)"
}
},
"additionalProperties": false
}Checks the availability of 1-3 products (EANs) at every OBI, Bauhaus, toom, Hornbach, hagebau and Globus store within radiusKm (1-30, default 10) of a German postal code, based on the retailers' pages. Returns per product and retailer: status (read; not_listed_in_our_data = watch.diy knows no listing of this product at that retailer, which may still sell it; no_store_in_radius), the retailer's product name, its product page url, price with priceAsOf (a price older than 35 days is returned as null with priceNote), and stores [{name, city, zip, km, state, updated}]. Store state is one of available, not_available, not_sold_in_store, unknown: available (the retailer's page shows it as available at that store), not_available (the retailer's page shows it as not available at that store; it does not mean the store never carries it), not_sold_in_store (the retailer does not sell it in that store), unknown (no information for that store). updated is "recently" (within the last 24 hours) or a date (YYYY-MM-DD). Also returns partial (true when there is no information for some stores), location {plz, radiusKm} and a notice. Can take a few seconds. Limits: public lookups are limited per client and per day. Errors: invalid_request (names the field and the reason, e.g. an unknown postal code), quota_exceeded (with the minutes until it can be tried again), public_unavailable.
| Argument | Type | Description |
|---|---|---|
| plz* | string | German postal code (PLZ), 5 digits |
| products* | array | 1-3 EANs (GTIN barcodes, 8-14 digits), each once |
| radiusKm | number | Kilometres around the postal code, 1-30 (default 10) |
We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 14, 2026.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"products",
"plz"
],
"properties": {
"plz": {
"type": "string",
"pattern": "^\\d{5}$",
"description": "German postal code (PLZ), 5 digits"
},
"products": {
"type": "array",
"items": {
"type": "string",
"pattern": "^\\d{8,14}$"
},
"maxItems": 3,
"minItems": 1,
"description": "1-3 EANs (GTIN barcodes, 8-14 digits), each once"
},
"radiusKm": {
"type": "number",
"default": 10,
"maximum": 30,
"minimum": 1,
"description": "Kilometres around the postal code, 1-30 (default 10)"
}
},
"additionalProperties": false
}