streamable-httpMITupdated 7d ago
MCP server for the waste collection calendars of German cities and districts. Looks up collection dates β residual waste, organic waste, paper, packaging, bulky waste, hazardous waste collection points β for a given address.
What can you do with Abfallkalender Deutschland?
abfall-mcp-server
English Β· Deutsch
MCP server for the waste collection calendars of German cities and districts. Looks up collection dates β residual waste, organic waste, paper, packaging, bulky waste, hazardous waste collection points β for a given address.
Website and interactive setup guide:
abfall-mcp.alpaycelik.dev.
address βββΆ Nominatim βββΆ municipality + district βββΆ provider search (995)
β
collection dates βββ portal βββ resolve arguments
Why this is not trivial
Waste management in Germany is organised municipally. There is no nationwide API β roughly 400 public waste authorities each run their own portal, backed by a handful of software platforms (Abfall.IO/AbfallPlus, AbfallNavi, Jumomind, AWIDO, C-Trace, MΓΌllmax, plus many plain ICS exports).
This server uses
mampfes/hacs_waste_collection_schedule
(MIT) as its data source β an actively maintained project with over 950 source
modules. Its inner package is independent of Home Assistant and is wired in
here as a Git submodule.
The actual work of this project is turning an address into the responsible waste authority and its internal parameters. In Home Assistant a human clicks that together once; an MCP server has to do it on its own.
Installation
The server runs from a repository checkout, not as an installed package: it
needs the data source under vendor/ and the registry under data/, both
resolved relative to the project root. That is also why it is not on PyPI β a
wheel would install cleanly and still not work.
git clone --recurse-submodules https://github.com/AlpayC/abfall-mcp-server.git
cd abfall-mcp-server
uv sync
uv run pytest
data/providers.json is checked in, so the server starts right away. After a
submodule update, rebuild it:
uv run python scripts/build_registry.py
Wiring it up
Public remote via Streamable HTTP:
{
"mcpServers": {
"abfall": {
"url": "https://abfall-mcp.alpaycelik.dev/mcp"
}
}
}
The service health endpoint is
https://abfall-mcp.alpaycelik.dev/health.
Locally over stdio β in claude_desktop_config.json or .mcp.json:
{
"mcpServers": {
"abfall": {
"command": "uv",
"args": ["--directory", "/path/to/abfall-mcp-server", "run", "abfall-mcp-server"]
}
}
}
As an HTTP service:
uv run abfall-mcp-server --http --host 127.0.0.1 --port 8000
Keep in mind that every HTTP request puts load on the authorities' portals and
on Nominatim. For anything beyond personal use, put a cache in front and your
own Nominatim instance behind it (ABFALL_MCP_NOMINATIM_URL).
Tools
Tool names and responses are German, because the domain and the users are.
| Tool | Purpose |
|---|---|
abfuhrtermine |
Address in, collection dates out. The usual entry point. |
finde_traeger |
Search authorities by place or company name, no geocoding. |
traeger_details |
Which arguments does an authority expect? |
abfuhrtermine_fuer_traeger |
Targeted query, e.g. to answer a follow-up question. |
abdeckung |
How many authorities and data sources are covered. |
Plus the resource abfall://traeger with the full list of authorities.
Asking beats guessing
When a value cannot be determined unambiguously, the server returns
status: "rueckfrage" along with the concrete list of options instead of
guessing. That is deliberate: a wrongly guessed town cheerfully returns the
neighbouring municipality's calendar β a wrong answer that looks like a right
one.
Coverage, measured
scripts/build_registry.py collects 995 waste authorities from 150 source
modules.
scripts/smoke.py queries real addresses against the real portals. A run over
21 addresses across Germany (as of Aug 2026):
| Outcome | Share |
|---|---|
| Collection dates returned directly | 48 % |
| Follow-up question for a missing detail | 14 % |
| No authority returned dates | 38 % |
That is the measured number, not an estimate β and the reason to state it here: "covers every German city" is true of the authority list, not of fully automatic resolution from a bare address.
Authorities with their own ID lookup
Some portals require internal identifiers that cannot be derived from an
address. For these, the portal's address dialog is reimplemented in
lookup.py:
| Authority | Identifier | Scope |
|---|---|---|
| Abfall.IO / AbfallPlus | f_id_kommune, f_id_strasse, β¦ |
41 authorities |
| Stadtreinigung Hamburg | hnId |
Hamburg |
| Berliner Stadtreinigungsbetriebe | schedule_id |
Berlin |
The upstream wizard for Hamburg is stale by now β the portal moved its form to a JavaScript component, whose address endpoint is read out of the page here.
Where the remaining cases fail
- Further ID arguments with no lookup path:
standortin Dresden,idHouseNumberin Leipzig,streetnrin Stuttgart. One more resolver each, following the same pattern as the three above. - Portals using different spellings that ship no list of suggestions (Erfurt, Kiel).
- Outages, rate limiting and malformed responses on the authorities' side (SaarbrΓΌcken returns HTML instead of ICS).
Layout
| File | Responsibility |
|---|---|
wcs.py |
Bridge to the vendored library; registers the package deliberately instead of putting it on sys.path (its parent directory holds a calendar.py that shadows the stdlib). |
registry.py |
Authority list and location search with German stemming. |
geo.py |
Nominatim, address variants, plausibility checks. |
resolve.py |
Address β authority β resolved arguments β collection dates. |
lookup.py |
Address dialogs for authorities with internal IDs (Abfall.IO, Hamburg, BSR). |
server.py |
MCP tools, stdio and HTTP. |
The registry is not built at runtime: data/providers.json is produced by a
script so that starting the server does not import 150 modules. Rebuild it
after a submodule update.
Data sources and usage
Collection dates come from the portals of the respective waste authorities,
address resolution from Nominatim
(OpenStreetMap). Nominatim has a usage policy β at most one request per second;
the server honours it and caches results in ~/.cache/abfall-mcp-server/.
For dates something depends on (bulky waste, hazardous waste collection), it is worth checking the portal address that every response carries.
Contributing
The most useful contribution is a report that some authority does not work β there is an issue template with the right questions. How to add an authority resolver is in CONTRIBUTING.md; security issues belong in a private report, see SECURITY.md. Changes are listed in the CHANGELOG. Agents working on this repository should read AGENTS.md.
One principle runs through the whole project and applies to contributions too: when in doubt, ask β do not guess. A wrongly guessed town cheerfully returns the neighbouring municipality's calendar β a wrong answer that looks like a right one.
License
MIT, see LICENSE. The submodule
vendor/hacs_waste_collection_schedule is under its own MIT license,
Copyright (c) 2020 Steffen Zimmermann β this repository only references it, it
does not ship the code. Third-party attributions are collected in
NOTICE.
Install
Add Abfallkalender Deutschland to your client. Pick the one you use.
claude mcp add --transport http abfallkalender-deutschland https://abfall-mcp.alpaycelik.dev/mcpcodex mcp add abfallkalender-deutschland --url https://abfall-mcp.alpaycelik.dev/mcp{
"mcpServers": {
"abfallkalender-deutschland": {
"url": "https://abfall-mcp.alpaycelik.dev/mcp"
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
{
"servers": {
"abfallkalender-deutschland": {
"type": "http",
"url": "https://abfall-mcp.alpaycelik.dev/mcp"
}
}
}Add to `.vscode/mcp.json` in your workspace.
{
"mcpServers": {
"abfallkalender-deutschland": {
"url": "https://abfall-mcp.alpaycelik.dev/mcp"
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"abfallkalender-deutschland": {
"serverUrl": "https://abfall-mcp.alpaycelik.dev/mcp"
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
3 tools
Abfallkalender Deutschland exposes 3 tools to a connected agent.
- finde_traeger
- Search authorities by place or company name, no geocoding.
- traeger_details
- Which arguments does an authority expect?
- abfuhrtermine_fuer_traeger
- Targeted query, e.g. to answer a follow-up question.
Score
73 / 100
Good
- Documentation25/25
- Maintenance19/25
- Trust13/20
- Capability4/15
- Install experience12/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 0 days ago
- Has a release history
- Repository is not archived
- Licensed MIT
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 3 tool(s) documented
- Provides prompt templates
- Provides resources
- 6 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint β no local install
Version history
| Versions | Published |
|---|---|
| 0.2.0Latest | Aug 27, 2026 |