Projects · Calendar · refreshed weekly by an AI agent

Amsterdam theater planner

One calendar of what's on at 25 Amsterdam venues, with a view of the shows I can follow without speaking Dutch. An AI agent refreshes it every week and fixes whatever broke.

Sample output · snapshot of 3 October 2026See all 52 listings →
Sat 3 Oct · 15:00Public tour (in English)International Theater Amsterdam (Stadsschouwburg)English
Sat 3 Oct · 20:00Improv SpectacularBoom ChicagoEnglish
Sat 3 Oct · 22:15The Comedy EmbassyBoom ChicagoEnglish
Sun 4 Oct · 19:00Sunday Night LiveBoom ChicagoEnglish
Sun 4 Oct · 22:15The Comedy EmbassyBoom ChicagoEnglish
  • 25venues in one calendar
  • ~2,000listings at a time
  • 4 monthsahead, rolling
  • Weeklyrefresh by a scheduled agent

The problem I had

I like going to the theater, and in Amsterdam I kept running into the same two problems. Every venue has its own website and its own calendar, so finding out what’s on next Friday meant opening a dozen tabs. And most listings don’t say what language the show is in, which matters because my Dutch isn’t good enough for a play yet.

It started as a shortlist for one festival, the Amsterdam Fringe. When the festival ended I kept the part that collected the listings, because I wanted the same thing for the rest of the year.

How I went about it

Each listing gets a language code: English, non-verbal, English surtitles, Dutch, or not stated. My English-friendly view only includes a show when the listing says so. That means it misses some shows I could have followed. I’m fine with that, because missing a show costs me less than sitting through a play I can’t understand.

The part I expected to kill the project was maintenance. I have a small scraper for each of the 25 venue sites, and those break whenever a venue redesigns its page. So I handed that job to an AI agent.

Every week, without me
  1. RefreshA scheduled Claude session re-reads all 25 venues
  2. ReportIt reads what changed and what broke
  3. FixIt repairs the scrapers that broke
  4. SaveThe new calendar is saved for me

To make that work, a broken venue can’t take the rest down with it. When a site changes, the planner keeps that venue’s last good listings, marks them with a warning, and adds the venue to a “needs attention” list. The agent starts from that list.

What the agent starts from · illustration
Venue ARead fineOK
Venue BPage layout changed. Last good listings kept.Needs attention
Venue CRead fineOK

I didn’t build an app or a database. The output is a few Markdown pages and one spreadsheet file, which I can read on my phone and which costs nothing to run.

How it works

  1. ScrapeOne small scraper per venue reads the official program into a shared format.
  2. TrimOnly today through the next 120 days is kept.
  3. TagLanguage, genre and ticket status (sold out, cancelled) are read from each listing.
  4. BuildA calendar across all venues, the English-friendly view, a spreadsheet for filtering, and a page per venue.
  5. ReportA report says what changed and what broke. The weekly agent session starts from it.

How it’s worked out

I use it to decide what to book. It covers 25 venues, from the Concertgebouw and Carré to small fringe stages, with around 2,000 listings at any time.

The weekly refresh has kept running without me. The agent has also made improvements I didn’t ask for one by one, like picking up sold-out and cancelled labels at several venues.

Here’s a sample: three weeks of what’s on in English →

What I learned and where it could go

The language filter is the weakest part. About two thirds of listings don’t state a language at all, so the English-friendly view is a lot smaller than it should be. Recurring events are also shaky: one weekly storytelling night currently shows up on every day of the week.

I’d like to have it guess the language for the listings that don’t say, and show how sure it is. I’d also like to publish the English-friendly calendar as a page that updates itself each week, since I doubt I’m the only one in Amsterdam with this problem.

The code isn’t public because the same repository holds my personal shortlists.

Last updated 10 October 2026.