# TourismMCP (remote · ai.projektionisten.eu)

Travel in Germany (Tourismus): sights, events, opening hours and prices, weather and tides.

- Trust score: 36/100 (low)
- Change this week: 0
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-01

## Components

- remote · `ai.projektionisten.eu`: 36/100 (this document), [markdown](https://verifymcp.io/servers/eu-projektionisten-tourism/tmcp.md), [page](https://verifymcp.io/servers/eu-projektionisten-tourism/tmcp)

## Channel facts

- Endpoint: `https://ai.projektionisten.eu/tmcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `0.1.2`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-01.

- **Endpoint Security**: 89/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - The endpoint enforces authorisation, advertised via RFC 9728 protected-resource metadata.
  - HTTPS is enforced; there's no plaintext access path.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
  - The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents.
- **Transport & Reachability**: 0/100
  - Transport blocked by authentication: the endpoint requires auth we don't have to verify streamable-http.
- **Schema Quality & AI Usability**: 0/100
  - Schema blocked by authentication: the endpoint requires auth we don't have to read it.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 0/100
  - Tool coverage blocked by authentication: the endpoint requires auth we don't have to read its tools.
- **Tool Safety**: 0/100
  - Tool safety blocked by authentication: the endpoint requires auth we don't have to read its tools.
- **Capabilities**: 0/100
  - Capabilities blocked by authentication: the endpoint requires auth we don't have to read them.

**Unverified: 6 categories.** Categories scored 0 because we could not verify them: authentication we do not have, an unreachable endpoint, or not enough scan history. We only credit what we can confirm.

## Install

### How do I install the TourismMCP MCP server?

TourismMCP is a hosted endpoint at https://ai.projektionisten.eu/tmcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add --transport http eu-projektionisten-tourism 'https://ai.projektionisten.eu/tmcp'
```

### Cursor

```json
{
  "mcpServers": {
    "eu-projektionisten-tourism": {
      "url": "https://ai.projektionisten.eu/tmcp"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "eu-projektionisten-tourism": {
      "type": "http",
      "url": "https://ai.projektionisten.eu/tmcp"
    }
  }
}
```

### Codex

```toml
[mcp_servers.eu-projektionisten-tourism]
url = "https://ai.projektionisten.eu/tmcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "eu-projektionisten-tourism": {
      "type": "remote",
      "url": "https://ai.projektionisten.eu/tmcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add eu-projektionisten-tourism --url 'https://ai.projektionisten.eu/tmcp' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  eu-projektionisten-tourism:
    url: "https://ai.projektionisten.eu/tmcp"
```

### Netclaw

```json
{
  "McpServers": {
    "eu-projektionisten-tourism": {
      "Transport": "http",
      "Url": "https://ai.projektionisten.eu/tmcp"
    }
  }
}
```

### Vellum

```bash
assistant mcp add eu-projektionisten-tourism -t streamable-http -u 'https://ai.projektionisten.eu/tmcp'
```

### Other

```json
{
  "mcpServers": {
    "eu-projektionisten-tourism": {
      "type": "http",
      "url": "https://ai.projektionisten.eu/tmcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-09-28 (score 36, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-09-25 (score 36, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-09-23 (score 36, −41)

- [security regression] Endpoint reachability: reachable → behind authorisation
- [security regression] Tool safety: pass → unverified
- [security regression] Transport: pass → unverified
- [security] Authorization: The endpoint enforces authorisation, advertised via RFC 9728 protected-resource metadata.
- [security] Tool “expand_kg_pois” rewrote its description, which is the text the model reads
- [security] Tool “get_current_weather” rewrote its description, which is the text the model reads
- [security] Tool “get_poi_details” rewrote its description, which is the text the model reads
- [security] Tool “get_tide” rewrote its description, which is the text the model reads
- [security] Tool “get_weather_forecast” rewrote its description, which is the text the model reads
- [security] Tool “link_datetime” rewrote its description, which is the text the model reads
- [security] Tool “search_tourism” rewrote its description, which is the text the model reads
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Schema quality: 100 → unverified
- [functional improvement] Stability: unverified → 0.03
- [functional] Server version: 0.1.0 → 0.1.1

### 2026-09-22 (score 77)

First indexed and scored.

## MCP tools (14)

### `search_place` (~533 tokens)

Löst den NAMEN einer Stadt, Region oder eines Bezirks in Koordinaten und OSM-Ids auf — der erste Schritt, wenn ein GEBIET verortet werden muss („was kann ich in <REGION> unternehmen", „wie ist das Wetter in <CITY>"). **Für eine HALTESTELLE ist dieses Werkzeug fast immer falsch**: es kennt Gebiete, keine Bahnsteige — auf einen Bahnhofs-Namen antwortet es mit dem Stadtteil, und die Id, die es liefert, ist eine OSM-Id und keine fahrbare Halte-Id. **Trägt die Anfrage `Bahnhof`, `Hauptbahnhof`, `Hbf` oder `Bf`, gehört sie an die Ortsauflösung** — „Köln Hauptbahnhof" und „Hannover Bahnhof" also dorthin, nicht hierher: auf das erste antwortet dieses Werkzeug mit einem gleichnamigen Ortsteil (einem in Potsdam), auf das zweite mit der Stadt Hannover. Dasselbe für Adresse und POI — alles, was Start, Ziel oder Abfahrtsort einer Fahrt sein kann; eine Stadt als Fahrt-Endpunkt („von Hannover nach Celle") ebenfalls. Von einer Koordinate zurück zum Namen geht `reverse_geocode`, die Umgebung einer Koordinate listet `nearby`. **Pflicht**: `name`. **Optional**: `lang` — wird für Symmetrie mit den übrigen Geo-Werkzeugen angenommen, derzeit aber nicht ans Backend durchgereicht und ändert das Ergebnis nicht. **Anleitung**: `get_usage_guide` mit `tool='search_place'` — die Abgrenzung im Detail, die typischen Ketten und der Umgang mit einem mehrdeutigen Namen. **Anti-Fab**: nur die zurückgegebenen Namen und Ids nutzen, keine Bauch-Geographie.

Input parameters:

- `format` (string|null): Answer serialisation: `"toon"` (default) or `"json"` — the detail is in `get_usage_guide`. **An agent leaves this out.**
- `lang` (string|null): Optional ISO language code (e.g. "de", "en"). Currently advisory: the place names are the German ones the data carries, whatever is asked for. Kept in the signature so a multilingual answer needs no…
- `name` (string, required): Name of the place to search for. Free-text fuzzy match against the place index behind this endpoint (e.g. "Hannover", "Maschsee", "Wangerland").

### `resolve_location` (~960 tokens)

Löst Freitext in die Id auf, mit der gefahren wird — die Haltestelle, die Adresse oder den POI hinter „von <X> nach <Y>", „erzähl mir was über <POI>". Wo Routing, Abfahrtstafel oder POI-Steckbrief eine Id brauchen, steht es davor — auch wenn der Nutzer die Stadt dazu nennt („Hauptbahnhof Hannover"). Ein GEBIET (Stadt/Region) verortet `search_place`. **Pflicht**: `query` — nur der Name: `'Kelsterbach Bahnhof'`, NICHT `'für Kelsterbach Bahnhof'`. Wegzulassen sind `für`, `vom`, `von`, `nach`, `bis`; ein führendes `am`/`an`/`in`/`zur`/`auf` bleibt stehen — so heißen echte Halte („Am Wehrhahn"). **Optional**: `lat`/`lon` (Ranking-Bias), `limit`, `node_types` (`'stop'`/`'address'`/`'poi'`/`'any'`, mehrere mit Komma in EINEM String; eine andere Art ist ein Argument-Fehler), `city_station` (Query = ganze Stadt → deren (Haupt-)Bahnhof). **Art-Wort in `node_types`, nicht in den Namen**: „Haltestelle X" → `'stop'`, „Adresse X" → `'address'`, „POI X"/„Sehenswürdigkeit X" → `'poi'`, `query` je ohne das Wort. **A→B: zweimal rufen** — Start, Ziel. Jeder Treffer trägt `type` und `location`; NUR ein `stop` hat eine fahrbare DH-Id, nie eine erfinden. **Anleitung**: `get_usage_guide` — Abgrenzung, Argumente, Rangfolge. **Anti-Fab**: nur die Treffer aus dem Output dieses Aufrufs verwenden.

Input parameters:

- `city_station` (boolean|null): When `Some(true)` AND the query is a whole CITY, resolve it to the city's (Haupt-)Bahnhof stop and return ONLY that stop (so „von Hannover nach Celle" routes Bahnhof→Bahnhof). Forwarded to mobility-m…
- `format` (string|null): Answer serialisation: `"toon"` (default) or `"json"` — the detail is in `get_usage_guide`. **An agent leaves this out.**
- `lat` (number|null): Optional latitude (WGS-84) to bias ranking toward nearby stops.
- `limit` (integer|null): Maximum number of results. Defaults to 5 if omitted.
- `lon` (number|null): Optional longitude (WGS-84) to bias ranking toward nearby stops.
- `node_types` (string|null): Which kinds of place to resolve to: `"stop"`, `"address"`, `"poi"` or `"any"`. Several combine in ONE comma-separated string — `"stop,poi"`; an array of the same tokens is read as that string. A kind…
- `query` (string, required): Free-text query, e.g. "Hauptbahnhof Hannover" or "Linden Markt". Nur der reine Orts-/Haltename — ohne das Wort, das ihn im Satz ankündigt: `"Kelsterbach Bahnhof"`, nicht `"für Kelsterbach Bahnhof"`.…

### `nearby` (~894 tokens)

Findet Haltestellen, POIs und Adressen im Radius um eine KOORDINATE (Schwerpunkt Hannover/Niedersachsen) — „was ist in der Nähe von <lat,lon>", „welche Haltestellen liegen um diesen Punkt". Liegt nur ein Name vor, kommt erst eine Auflösung: `search_place` für eine Stadt oder Region, sonst die Ortsauflösung. **Pflicht**: `latitude`, `longitude`, `radius_m`. **Optional**: `limit` (Default 10); `node_types` — EIN String, mehrere Arten mit Komma: `'stop'`, `'address'`, `'poi'`, die Sharing-Angebote `'bike_rental'`, `'scooter_rental'`, `'car_sharing'`, `'taxi_stand'`, die Abstellanlagen `'park_and_ride'`, `'bike_and_ride'`, oder `'any'` (`'stop,bike_rental'`); `include_mots` (legt die bedienenden Linien über die Haltestellen-Treffer); `only_available` (nur Sharing-Treffer mit gemeldetem freiem Fahrzeug — UNBEKANNTE Verfügbarkeit gilt nicht als frei). **Format**: kompakter Einrück-Text (TOON), kein JSON. **Anleitung**: `get_usage_guide` mit `tool='nearby'` — die Werte im Einzelnen, was `'any'` nicht abdeckt, und was ein Treffer trägt (`category`, `modality`, `parking`, `contactInfo`). **Anti-Fab**: nur die zurückgegebenen Namen, Typen, Distanzen und Verfügbarkeiten nennen; fehlt ein Feld, war es in der Quelle nicht getaggt — Öffnungszeiten und Preise stehen hier NICHT.

Input parameters:

- `format` (string|null): Answer serialisation: `"toon"` (default) or `"json"` — the detail is in `get_usage_guide`. **An agent leaves this out.**
- `include_mots` (boolean|null): `true` overlays the serving transit lines on stop results. Default `false`, which keeps the answer small.
- `latitude` (number, required): Latitude in WGS-84 decimal degrees.
- `limit` (integer|null): Maximum number of results, at least 1. Default 10.
- `longitude` (number, required): Longitude in WGS-84 decimal degrees.
- `node_types` (string|null): Which kinds of place to answer with: the places the graph holds — `"stop"`, `"address"`, `"poi"` — plus the shared-mobility offers `"bike_rental"`, `"scooter_rental"`, `"car_sharing"` and `"taxi_stan…
- `only_available` (boolean|null): Set to `true` for „wo kann ich JETZT eines nehmen": of the shared-mobility offers, only those whose live feed reports at least one vehicle ready to be taken are answered with. A station whose availab…
- `radius_m` (number, required): Search radius in metres.

### `reverse_geocode` (~777 tokens)

Benennt, was an einer KOORDINATE liegt — der Ort („was liegt bei <lat,lon>"), mit `level` eine bestimmte Ebene davon, mit `level='street'` die Straße samt nächster Hausnummer (der Lookup für eine GPS-Startposition). **Abgrenzung**: den Weg zurück (Name → Koordinate und OSM-Ids) geht `search_place`, die fahrbare Halte-Id liefert die Ortsauflösung, und `nearby` listet auf, was UM eine Koordinate liegt, statt den Punkt selbst zu benennen. **Pflicht**: `lat` und `lon` — geschrieben auch `latitude`/`longitude`, so wie `nearby` die Koordinate nimmt; je Aufruf nur eine der beiden Schreibweisen. **Optional**: `radius_m` (Suchradius in METERN; ein Ort, IN dem die Koordinate liegt, hat Abstand 0 und ist in jedem noch so engen Radius dabei — ohne `radius_m` die nächstgelegenen Treffer), `limit` (Höchstzahl Treffer, Default 10, Maximum 50) und `level` — `'place'` (Default: die ganze Ortshierarchie, feinste Ebene zuerst), `'city'` (die Stadt/Gemeinde), `'suburb'` (der Stadtteil) oder `'street'`. Kennt der Datensatz die gewünschte Ebene hier nicht, antwortet die nächst-gröbere, erkennbar am `place_type`; ein unbekannter Wert wirkt wie `'place'`. **Anleitung**: `get_usage_guide` mit `tool='reverse_geocode'`. **Anti-Fab**: nur die zurückgegebenen Orts- und Straßen-Namen verwenden, einschließlich der Hausnummer aus dem Datensatz — nie eine erfinden.

Input parameters:

- `format` (string|null): Answer serialisation: `"toon"` (default) or `"json"` — the detail is in `get_usage_guide`. **An agent leaves this out.**
- `lat` (number, required): Latitude of the coordinate to reverse-geocode. Also accepted spelled `latitude`, the way the vicinity search takes it — one of the two spellings per call.
- `level` (string|null): Optional resolution level. `"place"` (default) answers with the coordinate's whole admin hierarchy, finest first (suburb → town → county → state → country); `"city"` with the town/municipality it lie…
- `limit` (integer|null): Optional maximum number of hits, nearest first. Default 10, upper bound 50; a larger value is served as 50 and `0` as the default. Applies to every level and with or without `radius_m`.
- `lon` (number, required): Longitude of the coordinate to reverse-geocode. Also accepted spelled `longitude`, the way the vicinity search takes it — one of the two spellings per call.
- `radius_m` (number|null): Optional radius in METRES. When set, returns the places inside the circle, sorted nearest-first and capped to `limit`. A place the coordinate LIES INSIDE is at distance 0 and is therefore in every ra…

### `get_poi_details` (~1085 tokens)

POI-Detail-Lookup per OSM-ID (Daten aus OpenStreetMap). Für „Öffnungszeiten von X", „erzähl mir was über X" ist dieses Werkzeug die Auskunft, nicht das Allgemeinwissen — erst verorten, dann abfragen: die `osm_id` stammt aus `nearby`/`resolve_location`/`search_place`. **When to use**: nach `nearby` / `resolve_location` / `search_place` lieferte einen POI mit `osm_id` und die Anfrage will Detail-Info — DE: „erzähl mir was über <POI>", „was kostet der Eintritt", „Öffnungszeiten von <POI>", „bei dem Wetter in <REGION> unternehmen". EN: „tell me about <POI>", „opening hours of <POI>", „what can I do in <REGION> given the weather". **When NOT to use**: für Stadt-/Region-IDs (nutze `search_place`); ohne vorherigen Tool-Call mit OSM-ID-Output (KEIN raten); wenn die Anfrage Routing/Abfahrten will (dafür der Server MobilityMCP). **Required args**: `osm_id` — bare numeric string (pattern `^\d+$`, z.B. "296222553"), kein `node:`/`way:`-Prefix (der wurde beim emittierenden Tool bereits gestrippt). **Typical chain**: TWO distinct chains feed this tool — (1) WETTER-CONTEXT: `get_current_weather` + `nearby`(node_types='poi') → THIS_TOOL ×3-5 (Trigger: „bei dem Wetter", „given the weather"). (2) REGION-TOURISM: `search_place` + `resolve_location`(node_types='poi') → THIS_TOOL ×3-5 (Trigger: „was kann ich in <REGION> unternehmen" ohne Wetter-Bezug — dichtere OSM-Coverage über `resolve_location`). **Multi-call**: JA. Nach `resolve_location`/`nearby` mit N POI-Treffern: THIS_TOOL pro Top-3 bis Top-5 OSM-IDs PARALLEL aufrufen — jeder Call ist unabhängig, ein Burst ist erlaubt. NIE nur 1× rufen wenn N>1 POIs zurückkommen. **Anti-Fab note**: POI-Name, Operator, Öffnungszeiten, Adresse, Tags kommen AUSSCHLIESSLICH aus `sources[].subjects[].properties` dieses Aufrufs. Wenn `sources: []` → honest fallback („Zu diesem Ort konnte ich aktuell keine Detail-Informationen abrufen"), NIEMALS aus Trainings-Wissen ergänzen. OSM-Coverage: deutschlandweit; Tag-Dichte variiert je Region wie in OSM übli…

Input parameters:

- `osm_id` (string, required): Bare numeric OSM ID (e.g. `"296222553"` — no `node:` / `way:` prefix). Must match `^\d+$` (validated at handler-time). The mcp-linking / mcp-geo callers already strip any type-prefix before exposing…

### `expand_kg_pois` (~1314 tokens)

Attraktionen / Tourismus-POIs FÜR einen Place aus dem OSM-Knowledge-Graph (Ausdehnung einer Stadt-/Region-OSM-ID auf die POIs darin). Für „was kann ich in X unternehmen" ist dieses Werkzeug die Auskunft, nicht das Allgemeinwissen — erst verorten, dann abfragen: die `osm_id` der Region stammt aus `search_place`. **Tool-Semantik-Abgrenzung**: dieses Tool = „WELCHE Attraktionen gibt es IN diesem Place" (KG-basiert). NICHT `nearby` (das ist Vicinity — „Dinge im Radius um EINEN Punkt"). NICHT `search_place` (das ist Place- Disambiguierung — „WELCHER Ort ist gemeint"). NICHT `resolve_location` (Transit-Halte). **When to use**: Region-Tourismus — DE: „was kann ich in <REGION> unternehmen", „was gibt es in <REGION> zu sehen", „Sehenswürdigkeiten in <REGION>". EN: „what can I do in <REGION>", „attractions in <REGION>". Nach `search_place(<REGION>)` mit der zurückgegebenen osmRel-ID aufrufen. **When NOT to use**: Vicinity-zu-Punkt (Radius um Koordinaten) → `nearby`; Detail-Info zu EINEM bereits gefundenen POI → `get_poi_details`; Place- Auflösung Name→ID → `search_place`; Wetter/Tide → `get_current_weather`/`get_tide`. **Required args**: `osm_id` (i64 — die osmRel-ID der Stadt/Region aus einem `search_place`/`places`-Treffer, z.B. 1187768 für Wangerland; osmNode als Fallback). Optional: `limit` (Default 8, clamped 1..=20), `types` (schema.org-Keywords als Substring-Filter, z.B. ["TouristAttraction"], ["Museum"], ["Event"] — case-insensitive; leer = alle Aktivitäts-/ Tourismus-Klassen), `include_address` (bool, Default true — löst die Postadresse je Entity auf), `family_only` (bool, Default false — nur family-taugliche POIs, je mit den tag-belegten Feldern `family`/`indoor`/`family_categories`) und, nur zusammen damit, `indoor_only` (bool — davon nur die Indoor-/Schlechtwetter-tauglichen). **Unterkünfte ausgeschlossen**: dieses Tool ist der Aktivitäts-/„unternehmen"- Pfad — Unterkünfte (`tourism`=hotel/hostel/guest_house/motel/apartment/… ) werden backend-seitig AUSGESCHLOSSE…

Input parameters:

- `family_only` (boolean|null): Family mode: query the OSM family allowlist (playground/zoo/aquarium/beach/water_park/…) and keep/rank only family-suitable POIs, each carrying the derived `family`/`indoor`/ `family_categories` fiel…
- `include_address` (boolean|null): Whether to also resolve each entity's structured postal address (locality, region, postal code) with an extra lookup. Defaults to true.
- `indoor_only` (boolean|null): Restrict the family result to indoor (rain-safe) POIs (aquarium/indoor_play). Only meaningful with `family_only=true`.
- `limit` (integer|null): Maximum number of enriched tourism entities to return (default 8, clamped to 1..=20).
- `osm_id` (integer, required): OpenStreetMap relation/node ID of the city/region (e.g. 1187768 for Wangerland). Use the osmRel id from a `places` result (preferred) or osmNode as fallback.
- `types` (array|null): Optional schema.org type keywords to narrow the result, e.g. ["TouristAttraction"], ["Hotel"], or ["Event"]. Matched case-insensitively as substrings against each entity's schema.org rdf:type. When o…

### `search_tourism` (~2873 tokens)

Kuratierte Tourismus-Suche des Niedersachsen-Hubs — die redaktionelle TIEFE die OSM fehlt: EVENTS MIT DATUM, PREISE, Beschreibungen, Medien, Öffnungszeiten, Touren. Für „welche Veranstaltungen sind in X", „was kostet der Eintritt" ist dieses Werkzeug die Auskunft, nicht das Allgemeinwissen — erst verorten, dann abfragen: `region`/`query` aus der Frage, `lat`/`lon` nur aus `search_place`. **Tool-Semantik-Abgrenzung**: dieses Tool = die kuratierte Quelle. NICHT `expand_kg_pois` (das ist OSM-BREITE — alle Tags, all-NDS, aber ohne Events/ Preise/Redaktion). Für Region-Tourismus dürfen BEIDE laufen (OSM-Breite ∥ NDS-Kuration). NICHT `nearby` (Radius-um-Punkt), NICHT `search_place` (Place-Disambiguierung). **When to use**: Events — DE: „was ist diese Woche/am Wochenende in <Region> los", „Veranstaltungen in <Ort>". EN: „events in <Region> this weekend". Unterkünfte/Gastro — DE: „Hotels in <Ort>", „Restaurants in <Ort>". EN: „hotels/restaurants in <Ort>". Touren — DE: „touristische Radrouten/Radtouren in <Region>", „Radwanderwege/Wanderwege am <Ort>" → `type=tour`; jede Tour trägt dann `length_m`, `duration_min`, `ascent_m`/`descent_m`, `round_trip` und `activities` (wörtlich, als was der Datensatz sie führt: „Fahrrad", „E-Bike", „Wandern", „Kanu") — DARAN auswählen, nicht am Namen. Bei mehreren die best-passende per `get_tourism_details` zeichnen, die anderen namentlich nennen und fragen, welche noch. **When NOT to use**: reine OSM-Breite/„alle Sehenswürdigkeiten per Tags" → `expand_kg_pois`; Detail zu EINEM Treffer → `get_tourism_details`; Routing/ Abfahrten, auch „von A nach B mit dem Rad" → der Server MobilityMCP; Wetter/Tide → `get_current_weather`/`get_tide`. **Required args**: `region` ODER `query` (eines von beiden — Freitext-Region/ Name, z.B. region="Wangerland", query="Sielhafenmuseum"). Optional: `type` (genau eines von "event" | "poi" | "accommodation" (="hotel") | "gastro" (="restaurant") | "tour" — kuratierte Rad-/Wander-Routen, auch als "radtour"/"radroute…

Input parameters:

- `activity` (string|null): How a TOUR is travelled, for `type=tour`: "wandern" (also "wanderweg", "spaziergang", "hiking", "zu Fuß"), "fahrrad" (also "radtour", "e-bike", "mountainbike", "cycling") or "kanu" (also "paddeln", "…
- `family_only` (boolean|null): Family mode: search the curated NDS family categories (Tierpark/Freizeitpark/Spielplatz/Erlebnisbad/Badesee/Kletterpark/…) and overlay the curated suitability axis (age bands, Kinderwagentauglich, Ki…
- `indoor_only` (boolean|null): Restrict to rain-safe family records (the `suitability.indoor_bad_weather` / Schlechtwetterangebot proxy). Only meaningful with `family_only=true`.
- `lat` (number|null): Coord-vicinity mode — center latitude. When `lat` AND `lon` are both given the search becomes a vicinity search around the point: only curated hits within `radius_m` are returned (proximity-filtered…
- `limit` (integer|null): Maximum number of curated entities to return (default 8, clamped 1..=20).
- `lon` (number|null): Coord-vicinity center longitude (paired with `lat`).
- `query` (string|null): Free-text query (name / keyword) when not searching a whole region, e.g. "Sielhafenmuseum". Alias for `region`; one of the two is required.
- `radius_m` (integer|null): Coord-vicinity radius in metres (default 2000, clamped 100..=20000).
- `region` (string|null): Region or place to search within, as free text (e.g. "Wangerland", "Hooksiel", "Hannover"). Either `region` or `query` must be given; `region` is the natural choice for a place-scoped tourism search.
- `timeframe` (string|null): Optional event-date window for `type=event`: "today", "tomorrow", "weekend", "this_week", "month", or an explicit ISO date "YYYY-MM-DD" / range "YYYY-MM-DD..YYYY-MM-DD". With no timeframe the additiv…
- `type` (string|null): Content type to narrow the search. One of: "event", "poi", "accommodation" (a.k.a. "hotel"), "gastro" (a.k.a. "restaurant"), "tour". Omit to search across all curated types. Unknown values are treate…

### `get_tourism_details` (~1322 tokens)

Kuratiertes Detail zu EINEM Niedersachsen-Hub-Treffer per `id` — Beschreibung, Öffnungszeiten, ECHTER Preis, Adresse, Medien. Für „was kostet der Eintritt für X", „wann hat X geöffnet" ist dieses Werkzeug die Auskunft, nicht das Allgemeinwissen. **Tool-Semantik-Abgrenzung**: dieses Tool = Detail zu EINEM kuratierten NDS-Treffer (dessen `id`/`global_id`). NICHT `get_poi_details` (das ist die OSM-Detail-Bridge per OSM-ID). NICHT `search_tourism` (das ist die kuratierte Region-/Typ-SUCHE die die `id` erst liefert). **When to use**: nach `search_tourism` lieferte einen Treffer mit `id` und die Anfrage will Detail/Preis/Öffnungszeiten — DE: „was kostet der Eintritt für <Treffer>", „Öffnungszeiten von <Treffer>", „erzähl mir mehr zu <Event>". EN: „opening hours / price of <hit>". **When NOT to use**: ohne vorherigen `search_tourism`-Treffer mit `id` (KEIN raten/erfinden einer id); OSM-POI-Detail per OSM-ID → `get_poi_details`; Region-Suche → `search_tourism`. **Required args**: `id` (die `id` ODER `global_id` aus einem `search_tourism`-Treffer, z.B. "e_101102405"). Optional: `query` (Region/ Name-Hint — dieselbe Region wie bei der Suche; die kuratierte Quelle hat KEINEN Objekt-per-id-Endpunkt, daher re-sucht das Detail diesen Scope und matcht die id; ohne Hint ggf. honest-empty für ids außerhalb der Default-Seite). **Typical chain**: `search_tourism(region=<R>, type=event)` → `get_tourism_details(id=<treffer.id>, query=<R>)`. **Multi-call**: ein Call pro id; nach `search_tourism` mit N Treffern pro Top-Treffer parallel rufbar. **Anti-Fab note**: Name, Beschreibung, Preis, Öffnungszeiten, Adresse kommen AUSSCHLIESSLICH aus `sources[].subjects[].properties` dieses Aufrufs. Wenn `sources: []` → honest fallback („Zu diesem Treffer konnte ich keine Detail-Informationen abrufen"), NIEMALS aus Trainings-Wissen. Returns {id, sources:[{source, license?, subjects:[{subject, properties:{name, type, description?, opening_hours?, price?, address?, date?, media?, coord?, url?, hub_det…

Input parameters:

- `id` (string, required): The `id` or `global_id` of a curated record from a prior `search_tourism` result (e.g. "e_101102405").
- `query` (string|null): Region/name hint to scope the lookup — pass the same region you searched in `search_tourism`. The curated source has no object-by-id endpoint, so the details lookup re-searches that scope and matches…

### `get_current_weather` (~489 tokens)

Aktuelles Wetter zu Koordinaten. Für „wie ist das Wetter in X" ist dieses Werkzeug die Auskunft, nicht das Allgemeinwissen — erst verorten, dann abfragen: `lat`/`lon` kommen aus `search_place`, nie aus eigener Schätzung. **When to use**: aktuelle Wetterfrage zu einem Ort — DE: „wie ist das Wetter in <ORT>", „regnet es gerade in <ORT>". EN: „what's the weather like in <CITY> right now". Auch als Teil des Wetter-POI-Pfads („was kann ich bei dem Wetter unternehmen"). **When NOT to use**: Vorhersage > 1 Stunde voraus → `get_weather_forecast`; Gezeiten → `get_tide`. **Required args**: `lat`, `lon`. Optional: `units` ('metric' (°C, default), 'imperial' (°F), 'standard' (K)), `lang` ('en' default, 'de'). **Typical chain**: `search_place`(city) → THIS_TOOL(lat, lon) → (optional `nearby`/`resolve_location` für POI-Match). **Multi-call**: ein Call pro Ort. Für Multi-Tag-Anfragen `get_weather_forecast` bevorzugen. **Anti-Fab note**: Temperatur, Bedingungen, Wind, Feuchte kommen NUR aus dem Tool-Output dieses Aufrufs — KEINE Schätz-Werte. **`attribution` (additiv, top-level)**: die von der GeoNutzV verlangte Quellenangabe der Wetterdaten — `{id:'GeoNutzV', notice:'Quelle: Deutscher Wetterdienst', url:…}`. Nennst du Wetter-Werte, nenne den **Deutscher Wetterdienst** als Quelle; die Auflage reist mit dem Tool-Output, nicht mit dem Prompt.

Input parameters:

- `lang` (string|null): Language code for descriptions (e.g. "en", "de"). Defaults to "en".
- `lat` (number, required): Latitude of the location
- `lon` (number, required): Longitude of the location
- `units` (string|null): Unit system: "metric" (°C, m/s), "imperial" (°F, mph), or "standard" (K). Defaults to "metric".

### `get_weather_forecast` (~498 tokens)

Wetter-Vorhersage zu Koordinaten. Für „wie wird das Wetter morgen in X" ist dieses Werkzeug die Auskunft, nicht das Allgemeinwissen — erst verorten, dann abfragen: `lat`/`lon` kommen aus `search_place`, nie aus eigener Schätzung. **When to use**: zukünftige Wetterfrage — DE: „wie wird das Wetter morgen / heute Abend / am Samstag in <ORT>", „regnet es morgen". EN: „forecast for <CITY> tomorrow / this weekend". Auch für Halbtages-Touren-Planung („wenn das Wetter mitspielt"). **When NOT to use**: jetziger Zustand → `get_current_weather`; Tide → `get_tide`. **Required args**: `lat`, `lon`. Optional: `units` ('metric' default, 'imperial', 'standard'), `lang` ('en' default, 'de'), `limit` (Anzahl Forecast-Slots). **Typical chain**: `search_place`(city) → THIS_TOOL(lat, lon, limit=N) → (optional `resolve_location(node_types='poi')` + `get_poi_details` für POI-Auswahl je nach Wetter-Branche). **Multi-call**: ein Call pro Ort. Multi-Day-Queries decken sich über `limit`. **Anti-Fab note**: Vorhersage-Werte kommen NUR aus dem Tool-Output dieses Aufrufs — KEINE Tag-für-Tag-Schätzungen aus Trainings-Wissen. **`attribution` (additiv, top-level)**: die von der GeoNutzV verlangte Quellenangabe — `{id:'GeoNutzV', notice:'Quelle: Deutscher Wetterdienst', url:…}`. Nennst du Vorhersage-Werte, nenne den **Deutscher Wetterdienst** als Quelle.

Input parameters:

- `lang` (string|null): Language code for descriptions (e.g. "en", "de"). Defaults to "en".
- `lat` (number, required): Latitude of the location
- `limit` (integer|null): Maximum number of forecast entries to return
- `lon` (number, required): Longitude of the location
- `units` (string|null): Unit system: "metric" (°C, m/s), "imperial" (°F, mph), or "standard" (K). Defaults to "metric".

### `get_tide` (~482 tokens)

Gezeiten (Niedrig-/Hochwasser) für einen Küstenort. Für „wann ist Ebbe in X", „Gezeiten bei Y" ist dieses Werkzeug die Auskunft, nicht das Allgemeinwissen — erst verorten, dann abfragen: `city` aus der Frage oder `lat`/`lon` aus `search_place`. **When to use**: Gezeiten-/Ebbe-/Niedrigwasser-/Hochwasser-Frage — DE: „niedrigwasser in Cuxhaven", „wann ist Ebbe in Wilhelmshaven", „Tide bei Norderney". EN: „low tide in Cuxhaven", „when is high tide at Norderney". **When NOT to use**: normales Wetter → `get_current_weather`; Routing → der Server MobilityMCP; Haltestellen → `resolve_location`; Binnen-Orte ohne Küstenbezug (Hannover, Hildesheim, Braunschweig). **Required args**: entweder `city` (z.B. 'Hamburg', 'Cuxhaven', 'Norderney') ODER (`lat`+`lon`). Optional bei Koord-Mode: `station_limit`, `date_start`, `date_end` (YYYY-MM-DD). **Typical chain**: (optional `search_place`(city)) → THIS_TOOL. **Multi-call**: ein Call pro Ort/Tag-Range. **Anti-Fab note**: Tide-Zeiten kommen NUR aus dem Tool-Output dieses Aufrufs. KEINE „typischen" Tide-Schätzungen aus Bauch-Wissen.

Input parameters:

- `city` (string|null): City name to get tide data for (e.g. "Hamburg"). Use this or lat+lon.
- `date_end` (string|null): End date for tide data in YYYY-MM-DD format (only used with lat+lon)
- `date_start` (string|null): Start date for tide data in YYYY-MM-DD format (only used with lat+lon)
- `lat` (number|null): Latitude. Must be combined with lon. Use this or city.
- `lon` (number|null): Longitude. Must be combined with lat. Use this or city.
- `station_limit` (integer|null): Maximum number of tide stations to return (only used with lat+lon)

### `link_datetime` (~529 tokens)

Löst eine Zeit-Nennung in einen absoluten ISO-8601-Zeitpunkt auf — „morgen früh", „heute Abend um 18 Uhr", „in zwei Stunden", „um 8:30". Auch „jetzt"/„now"/„aktuell" wird aufgelöst: nutze das als kanonische Quelle für die aktuelle Zeit, statt dir selbst ein Datum auszudenken. Das Ergebnis (`candidates[].datetime_range.start`) ist der Zeitpunkt, mit dem du weiterarbeitest. Nennt der Nutzer bereits eine vollständige ISO-8601-Zeit mit Offset, ist kein Aufruf nötig. **Pflicht**: `text` — die Nennung, so wie der Nutzer sie schrieb. **Optional**: `lang` (`'de'` Default, `'en'`, `'fr'`) und `tz` (IANA-Name; ohne ihn wird die Lokalzeit als `Europe/Berlin` gelesen und als korrekter UTC-Instant zurückgegeben). **Was zurückkommt**: EIN Zeitpunkt, kein Fenster — `start` und `end` sind derselbe Instant. Eine nicht auflösbare Phrase liefert `candidates: []`; dann nachfragen, statt selbst zu rechnen. **Anleitung**: `get_usage_guide` mit `tool='link_datetime'` — insbesondere, auf welche Stunde eine vage Tageszeit fällt und was dann zu tun ist. **Anti-Fab**: Datum und Uhrzeit sind Fakten wie eine Liniennummer und stammen aus diesem Werkzeug — kein selbst-erfundenes Datum, keine eigene Datums-Arithmetik. Returns `candidates[].datetime_range:{start,end}`.

Input parameters:

- `format` (string|null): Answer serialisation: `"toon"` (default) or `"json"` — the detail is in `get_usage_guide`. **An agent leaves this out.**
- `lang` (string|null): Optional ISO language code (default `de`). Supported: `de`, `en`, `fr`.
- `text` (string, required): Free-text time mention to resolve via the rustling NLU. E.g. "morgen früh", "heute Abend um 18 Uhr", "in zwei Stunden".
- `tz` (string|null): Optional IANA timezone the stated local time is interpreted in (default `Europe/Berlin`). DST-aware. Pass e.g. `"Europe/Berlin"`; omit for the default. Determines the UTC instant emitted for a wall-c…

### `link_dynamic` (~275 tokens)

Match-Mention gegen Caller-supplied Kandidaten-Vokabular. **When to use**: Caller hat ein eigenes Vokabular (z.B. Custom-Enum, App-State, Domänen-spezifische Begriff-Liste) und will eine User-Mention darauf mappen. **When NOT to use**: Standard-Place/Stop/Time/MoT/Line-Linking → die spezialisierten `link_*`-Tools nutzen. Ohne Kandidaten ist der Linker leer. **Required args**: `text`, `candidates` (`[{name, synonyms?, coord?}, …]`) MUST be non-empty — die candidate-Liste IST das Vokabular. **Typical chain**: THIS_TOOL → (custom Caller-Logik). **Multi-call**: ein Call pro Mention/Vokabular-Set. **Anti-Fab note**: nur Kandidaten aus dem `candidates`-Arg matchen, KEIN impliziter Vokabular-Erweiterung. Returns `candidates[].candidate:<name>, score, span`.

Input parameters:

- `candidates` (array, required): Candidate vocabulary the linker should pick from. REQUIRED — the backend rejects empty candidate lists with 400.
- `text` (string, required): Free-text mention to match against the caller-supplied candidate list.

### `get_usage_guide` (~229 tokens)

Die ausführliche Anleitung zu den Werkzeugen dieses Katalogs: wofür ein Werkzeug da ist, wogegen es abzugrenzen ist, was seine Argumente bewirken, was zurückkommt und was daraus zitiert werden darf. Die `description` eines Werkzeugs ist die Kurzform, dieser Text die vollständige. **Optional** `tool` — der Name genau eines Werkzeugs, dessen Abschnitt du lesen willst; weggelassen kommt die ganze Anleitung. Lies den Abschnitt eines Werkzeugs, bevor du dessen Filter setzt oder ein leeres Ergebnis als Antwort weitergibst. **Der Abruf ohne `tool` ist teuer**: er bringt die Abschnitte ALLER Werkzeuge dieses Katalogs auf einmal, ein Vielfaches eines einzelnen. Setze `tool`, sobald feststeht, um welches Werkzeug es geht; ohne Argument nur für den Überblick über den ganzen Katalog.

Input parameters:

- `tool` (string|null): Der Name genau eines Werkzeugs aus diesem Katalog, dessen Abschnitt zurückkommen soll. Weglassen für die ganze Anleitung.

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/eu-projektionisten-tourism/tmcp#diagnostics

## Score history

- 2026-10-01: 36
- 2026-09-30: 36
- 2026-09-29: 36
- 2026-09-28: 36
- 2026-09-27: 36
- 2026-09-26: 36
- 2026-09-25: 36
- 2026-09-24: 36
- 2026-09-23: 36
- 2026-09-22: 77

## Common questions

### What is the TourismMCP MCP server?

TourismMCP is an MCP server listed in the public MCP registry as eu.projektionisten/tourism. Travel in Germany (Tourismus): sights, events, opening hours and prices, weather and tides. This page covers its hosted endpoint (https://ai.projektionisten.eu/tmcp).

### Is the TourismMCP MCP server safe to use?

TourismMCP scores 36 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the TourismMCP MCP server expose?

TourismMCP exposes 14 tools: search_place, resolve_location, nearby, reverse_geocode, get_poi_details, and 9 more. Their descriptions and schemas cost roughly 12,260 tokens of context every time the server is loaded.

### Does the TourismMCP MCP server require authentication?

Yes. TourismMCP asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.

### Is the TourismMCP MCP server still maintained?

TourismMCP is still listed as active in the MCP registry. We last reached this channel on 1 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- Remote endpoint: https://ai.projektionisten.eu/tmcp
- Website: https://ai.projektionisten.eu/mcp-landingpage/
- Changelog RSS feed: https://verifymcp.io/servers/eu-projektionisten-tourism/tmcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/eu-projektionisten-tourism/tmcp.json
- HTML version of this page: https://verifymcp.io/servers/eu-projektionisten-tourism/tmcp
