Skip to main content
Glama
jnslmk

kleinanzeigen-mcp

by jnslmk

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_listings

Search by keyword, location, radius and price range. Returns listing summaries.

get_listing

Full detail page for one listing id.

get_listings_batch

Full details for several ids at once — the normal follow-up to a search.

search_by_url

Search from a pasted Kleinanzeigen URL, preserving filters that search_listings cannot express (vehicle make, model year, room count, …).

parse_search_url

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:latest

The 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

MCP_TRANSPORT

http

http (streamable HTTP) or stdio

MCP_HOST

0.0.0.0

Bind address

MCP_PORT

8000

Bind port

MCP_PATH

/mcp

MCP endpoint path

KZ_MAX_CONTEXTS

4

Chromium browser contexts to pool

KZ_MAX_CONCURRENT

2

Concurrent scrapes

KZ_MAX_PAGE_COUNT

5

Cap on pages per search (~25 listings each)

KZ_MAX_BATCH_SIZE

20

Cap on ids per get_listings_batch call

LOG_LEVEL

INFO

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/mcp

Development

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_mcp

Upgrading 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.

Images

ghcr.io/jnslmk/kleinanzeigen-mcp — multi-arch (linux/amd64, linux/arm64), built by GitHub Actions on native runners for each architecture.

Tag

Meaning

latest

Newest build of main

sha-<full-sha>

A specific commit

v1.2.3, v1.2

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.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server to search tutti.ch Swiss classifieds anonymously with tools for listings, categories, and localities. Supports both MCP clients and a JSON CLI.
    17 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that searches Facebook Marketplace and Craigslist for items for sale, returning structured JSON listings with filtering, deduplication, and optional deep description checks.
    2
    MIT