kleinanzeigen-mcp
Enables searching Kleinanzeigen.de classifieds by keyword, location, radius, and price range; retrieving full listing details individually or in batch; searching from pasted Kleinanzeigen URLs while preserving filters such as vehicle make, model year, and room count; and parsing search URLs to explain the filters they encode.
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., "@kleinanzeigen-mcpfind a used bicycle in Berlin under 200€"
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.
kleinanzeigen-mcp
An MCP server that lets an LLM search Kleinanzeigen.de, Germany's largest classifieds site. Built for self-hosting: one container, no API keys, no per-query credits.
Scraping is done by DanielWTE/ebay-kleinanzeigen-api, which is baked into the image at a pinned commit. This project is the MCP layer on top.
Tools
Tool | What it does |
| Search by keyword, location, radius and price range. Returns listing summaries. |
| Full detail page for one listing id. |
| Full details for several ids at once — the normal follow-up to a search. |
| Search from a pasted Kleinanzeigen URL, preserving filters that |
| Explain which filters a URL encodes. Makes no network request. |
The intended flow is search_listings → pick interesting ids →
get_listings_batch. Search results deliberately omit descriptions so a broad
search does not blow up the model's context window.
Related MCP server: marketplace-search-mcp
Running it
docker run --rm -p 8000:8000 ghcr.io/jnslmk/kleinanzeigen-mcp:latestThe server speaks streamable HTTP at http://localhost:8000/mcp, with a plain
GET /healthz for container healthchecks. Set MCP_TRANSPORT=stdio to run it
as a local stdio server instead.
Chromium needs room to work — give the container at least 1.5 GB of memory.
Configuration
Variable | Default | Purpose |
|
|
|
|
| Bind address |
|
| Bind port |
|
| MCP endpoint path |
|
| Chromium browser contexts to pool |
|
| Concurrent scrapes |
|
| Cap on pages per search (~25 listings each) |
|
| Cap on ids per |
|
| Python log level |
The KZ_MAX_* defaults are tuned for a chat agent making one request at a time.
Raise them for throughput, at the cost of memory and a greater chance of
tripping Kleinanzeigen's bot detection.
LibreChat
mcpServers:
kleinanzeigen:
type: streamable-http
url: "http://kleinanzeigen-mcp:8000/mcp"
timeout: 120000
chatMenu: true
mcpSettings:
allowedAddresses:
- "kleinanzeigen-mcp:8000"allowedAddresses is required: LibreChat's SSRF guard blocks MCP URLs that
resolve to private addresses, which a sibling container always does. The
timeout is generous on purpose — a cold search has to start a browser context
and load real pages.
Claude Code
claude mcp add --transport http kleinanzeigen http://localhost:8000/mcpDevelopment
uv venv && uv pip install -e .
# The scrapers are not on PyPI, so point PYTHONPATH at a checkout of upstream:
git clone https://github.com/DanielWTE/ebay-kleinanzeigen-api.git /tmp/kz-api
pip install -r /tmp/kz-api/requirements.txt && playwright install chromium
PYTHONPATH=/tmp/kz-api python -m kleinanzeigen_mcpUpgrading the scraper
UPSTREAM_SHA in the Dockerfile pins the upstream commit. It is pinned rather
than tracking main because this server imports upstream's scraper functions
directly — ultra_optimized_scrape_inserate, get_inserate_details_optimized
and scrape_by_url — instead of going through its HTTP API. That avoids a
second process and an HTTP hop, but it means an upstream refactor can break this
image at runtime rather than at build time. Bump the SHA, rebuild, smoke-test
each tool, then ship.
patches/astro-results-fields.patch rides on top of the pin: Kleinanzeigen's
Astro relaunch (Sept 2026) dropped the classic card markup, and upstream's own
fix restored adid/url/title/location but not price, description or date — the
patch adds card-content fallbacks for those three. The Dockerfile applies it
with git apply --check, so when the pin moves past code the patch no longer
fits, the build fails loudly instead of silently shipping a regression.
Upstream absorbing this fix is the exit condition for the patch — drop it the
moment a newer pin makes it redundant.
Automated upstream updates
Renovate watches upstream main and opens a PR bumping UPSTREAM_SHA within
an hour of each upstream commit (hourly run dedicated to the pin; a weekly
pass covers the base image). Pin PRs are never automerged, and the patch
--check above is the compatibility gate: any PR whose pin outgrows the
patch goes red in CI.
Turning a red pin PR green is an AI-agent job: point a coding-agent session
at the PR and have it review the upstream diff
(git diff <old-pin>..<new-pin> in a clone of upstream), rework
patches/ if the touched code overlaps, confirm the build is green, then
smoke-test each tool against the rebuilt image before merging. Green pin PRs
still deserve the tool smoke test — a clean apply says nothing about runtime
behavior of the imported functions.
RENOVATE_TOKEN is a fine-grained GitHub PAT limited to this repository, with
Contents, Commit statuses, Issues, Pull requests, and Workflows read/write plus
Dependabot alerts read. It expires after 366 days; run
scripts/setup-renovate-token.sh to create or rotate it and install the
Actions secret without persisting its value locally.
Images
ghcr.io/jnslmk/kleinanzeigen-mcp — multi-arch (linux/amd64, linux/arm64),
built by GitHub Actions on native runners for each architecture.
Tag | Meaning |
| Newest build of |
| A specific commit |
| Release tags |
Caveats
Kleinanzeigen has no public API, so this scrapes the site with a headless browser. That means it can break whenever they change their markup, and heavy or parallel use may trip bot detection — particularly from a datacenter IP. Scraping is also at odds with Kleinanzeigen's terms of service. Keep it to personal-scale use.
License
MIT. Bundles DanielWTE/ebay-kleinanzeigen-api, also MIT — see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Search and browse global classifieds across 80 markets. No auth required for read-only access.
Etsy MCP — public listing search via Etsy Open API v3 (api_key auth only)
Federated listings from personal humanMCP servers. Search offers, trades by humans.
MCP server for real-time product search by barcode (EAN, UPC, GTIN) or keyword on ean-search.org
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceMCP server to search tutti.ch Swiss classifieds anonymously with tools for listings, categories, and localities. Supports both MCP clients and a JSON CLI.23 npmMIT
- AlicenseNot gradedqualityBmaintenanceMCP server that searches Facebook Marketplace and Craigslist for items for sale, returning structured JSON listings with filtering, deduplication, and optional deep description checks.2MIT
- AlicenseAqualityBmaintenanceRead-only MCP server for Marktplaats.nl (Dutch classifieds) that lets agents search listings and read price, specs, condition, delivery, location, and seller details.33 npmMIT
- FlicenseNot gradedqualityBmaintenanceEnables read-only access to Kleinanzeigen.de listings, including compact search, listing details, availability checks, and route calculations with optional distance and driving information.-