Claude Skill to get Stuttgart Waste Dates
Last year I experimented with MCPs by building one for waste removal dates in Stuttgart. I used this MCP in different settings since then to demonstrate what MCPs can do and I tried to use it to experiment with different services. But overall I am actually using a Python script that pushes the next waste removal dates to my Homeassistant.
Still I wanted to see how would this MCP look like as a Claude Skill.
This skill is saved in ~/.claude/skills/stuttgart-waste/SKILL.md.
And next to it the csv with all the streets of Stuttgart from the Github Repository of the str-ical2json MCP.
The SKILL.md I ended up with, looks like this:
--- allowed-tools: - Read(~/.claude/skills/stuttgart-waste/stuttgart_streets.csv) - Grep(path:~/.claude/skills/stuttgart-waste/stuttgart_streets.csv) - WebFetch(domain:service.stuttgart.de) --- # Stuttgart Waste Collection Dates 1. Extract **street name** and **house number** from the user's query. Ask if missing. 2. Validate against `stuttgart_streets.csv` (in this skill's directory). Columns: `street_name`, `house_count`, `numbers`, `type`. - Normalize "straße"/"strasse" to "str." for matching. - Fuzzy-match if no exact hit. Verify house number exists in `numbers`. 3. Fetch iCal via WebFetch: - URL: `https://service.stuttgart.de/lhs-services/aws/api/ical?street={street}&streetnr={streetnr}` - Use the street name as it appears in the CSV, URL-encoded. - Prompt: "Extract every VEVENT. For each, list DTSTART date (YYYY-MM-DD) and SUMMARY. Format: DATE | SUMMARY. List ALL events." 4. Show only **future dates**, grouped by waste type. **Default: next 1-2 dates per type.** Full list only if explicitly requested.
The permissions are allowing to read and grep the one csv file.
And the skill is only allowed to call the service.stuttgart.de domain to retrieve the ical data.
Finally one example call within an empty Claude Code shell:
❯ /stuttgart-waste for Katzenbachstrasse 58 ● Searched for 1 pattern, read 1 file (ctrl+o to expand) ● Fetch(https://service.stuttgart.de/lhs-services/aws/api/ical?street=Katzenbachstr.&streetnr=58) ⎿ Received 33.8KB (200 OK) ● Katzenbachstr. 58 — next pickups: ┌─────────────┬───────────────┬───────────────┐ │ Type │ Next │ After that │ ├─────────────┼───────────────┼───────────────┤ │ Restmüll │ Thu, 5 March │ Thu, 19 March │ ├─────────────┼───────────────┼───────────────┤ │ Biomüll │ Thu, 5 March │ Thu, 12 March │ ├─────────────┼───────────────┼───────────────┤ │ Altpapier │ Wed, 11 March │ Tue, 31 March │ ├─────────────┼───────────────┼───────────────┤ │ Gelber Sack │ Fri, 20 March │ Mon, 13 April │ └─────────────┴───────────────┴───────────────┘
The clear downside of this setup is, that you need to use Claude Code to get the answer. On the positive side: It is impressive with how little instructions this just works.
I started to build more skills.
For example one that fetches screenshots from my pastebin and reads it from /tmp.
That skill is mainly to allow the exact permissions to get the image without asking me.