listings
MCP serverDev toolsLive MCP for Immobilien Eichmann listings (Konstanz). Tools: search_listings, get_listing.
Available today. Use it from your connected AI after setup.
No other account needed.
Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
Then ask your AI: use listings to search listings
Install listings
The server’s own address, for the clients that take one directly. Or connect ahel once and every client you use reads it from one address, with the account kept on ahel rather than in each client’s config.
Claude Code
claude mcp add --transport http --scope user listings 'https://immobilieneichmann.de/mcp'Run it once in your project, then open /mcp to approve any sign-in the server asks for.
Claude Desktop
https://immobilieneichmann.de/mcpAdd a custom connector in Settings, paste this address, and approve the sign-in.
Cursor
cursor://anysphere.cursor-deeplink/mcp/install?name=listings&config=eyJ1cmwiOiJodHRwczovL2ltbW9iaWxpZW5laWNobWFubi5kZS9tY3AifQ==Open the link and Cursor adds the server at that address.
ChatGPT
https://immobilieneichmann.de/mcpIn Settings, enable Developer mode, create an MCP app, and paste this address. Your plan and workspace must allow custom apps.
Codex
codex mcp add listings --url 'https://immobilieneichmann.de/mcp'Run it once, then sign in with codex mcp login listings if the server asks for an account.
From the project's README
As published by christianhohlfeld/eichmannimmobilien in README.md.
Listings SoT (SQLite)
- Source of truth: SQLite on the droplet at
/var/lib/eichmann/listings.db(not in git, not in the web root). - Origins:
immowelt(inbound sync only) andeigen(own listings via unified/admin/#eigen). - Immowelt sync upserts/deactivates only
origin=immoweltand never deletesorigin=eigen. - Immowelt profile/account is read-only (no writes).
data/listings.jsonis an export/backup with"sot": "sqlite", not the SoT.- Publish:
node scripts/publish-from-db.mjswrites JSON export + HTML from the DB. - Admin: https://immobilieneichmann.de/admin/ — Immowelt visibility + Eigen CRUD. Auth = email + password → HttpOnly cookie via
/admin/api/(localhost Node). No GitHub PAT. - Badge for eigen listings: „nur bei uns“.
- Node on droplet: 20.x +
better-sqlite3. App tooling:/var/lib/eichmann/app. Admin API unit:eichmann-admin-api.service. - Stabschef note:
docs/STABSCHEF-admin-unified-2026-09-25.md
Immobilien Eichmann – technische Architektur und Betrieb
Statische Website für Immobilien Eichmann / Helmut Eichmann in Konstanz.
- Produktion: https://immobilieneichmann.de/
- Repository:
ChristianHohlfeld/eichmannimmobilien - Branch für Produktion:
main - Hosting: GitHub Pages
- Formular-Backend: eigener, getrennter Gateway-Dienst auf dem bestehenden VPS
- eigene Datenbank: keine
- produktiver Node-Prozess für Formulare:
dp-forms.serviceaufforms.digitalisierungsplanung.de
Stand dieser Dokumentation: 20.09.2026.
1. Architektur in einem Satz
Die öffentliche Website selbst besteht aus statischen HTML-, CSS-, JavaScript-, JSON- und Bilddateien auf GitHub Pages. Kontakt- und Exposé-Anfragen gehen an einen eigenen, technisch getrennten Formular-Gateway-Dienst unter forms.digitalisierungsplanung.de; weitere dynamische Abläufe laufen im Browser, über GitHub API / GitHub Actions oder über klar benannte Dienste wie Immowelt, Amazon SES und – nach Consent – Google Analytics.
Besucher
|
v
GitHub Pages / immobilieneichmann.de
|
+--> HTML + CSS + Vanilla JavaScript
|
+--> Kontakt-/Exposé-Anfrage
| Browser -> forms.digitalisierungsplanung.de -> Amazon SES -> info@immobilien-eichmann.com
|
+--> Analytics nur nach Consent
| Browser -> Google Analytics 4
|
+--> Externe Links
-> Immowelt / Google Maps
Admin-Browser
|
+--> GitHub REST API mit Sitzungs-PAT
| -> data/listings.json
| -> assets/listings/*
|
+--> repository_dispatch / workflow_dispatch
-> GitHub Actions
-> Renderer
-> generierte HTML-Seiten / Sitemap
-> Commit auf main
-> GitHub Pages Deployment
GitHub Actions Cron
|
+--> Playwright -> öffentliches Immowelt-Profil
-> Merge in data/listings.json
-> Bilder lokal spiegeln
-> HTML / Sitemap neu rendern
Die Website-Dateien selbst laufen weiterhin ohne Application Server auf GitHub Pages. Für Formulare existiert bewusst ein kleiner separater Node-Dienst auf dem vorhandenen digitalisierungsplanung.de-VPS. Er hat eigene Runtime/Env, keine gemeinsame Produkt-DB oder Session und speichert keine Formularinhalte in einer eigenen Datenbank. GitHub-Actions-Runner bleiben kurzlebige Build-/Automationsmaschinen.
2. Frontend-Stack
Die Website ist bewusst ohne Frontend-Framework gebaut.
| Ebene | Technik |
|---|---|
| Markup | HTML5 |
| Styling | eine eigene CSS-Codebasis in css/styles.css |
| Browserlogik | Vanilla JavaScript |
| Build-Bundler | keiner |
| React/Vue/Angular | keiner |
| jQuery | keiner |
| CSS-Framework | keines |
| Webfonts | keine externen Google Fonts; System-Font-Stacks |
| Bilder | JPG, WebP, PNG, SVG |
| SEO | statische Meta-Tags, Open Graph, Twitter Cards, JSON-LD, Sitemap |
| Deployment | GitHub Pages aus main |
Die Browserlogik liegt hauptsächlich in:
js/main.js– Navigation, Kontakt-/Exposé-Formulare, Flyer, Gallery, Lightbox, URL-Prefillsjs/cookie-consent.js– Consent-Speicherung und kontrolliertes Laden von Analyticsjs/analytics.js– Google Analytics 4 /gtag.js, Measurement IDG-QVRRBPYNVM
Für Objektseiten unter /objekt/ wird über window.__eichmannJsBase sichergestellt, dass die gemeinsamen JavaScript-Dateien mit dem korrekten relativen Pfad geladen werden.
3. Node-/Build-Stack
Dieses Repository benötigt Node lokal und in GitHub Actions für Generierung, Scraping, Bildverarbeitung und Tests. Der separate Formular-Gateway läuft serverseitig als Node-Dienst im Repository ChristianHohlfeld/digitalisierungsplanung.de; er ist nicht Teil des statischen GitHub-Pages-Deployments dieses Repositories.
package.json verlangt Node >= 20.
Direkte Dependencies:
| Paket | Verwendung | aktuell aufgelöst |
|---|---|---|
playwright | Browser-Automation: Immowelt-Import und Browser-Regressionsprüfungen | 1.63.0 |
sharp | Bildkonvertierung, Größenanpassung, Social-Share-Bilder | 0.33.5 |
Wichtige Befehle:
npm ci
npm run sync-immowelt
npm run sync-immowelt:render
npm run test:legal
npm run test:expose-form
npm run test:layout
npm run test:logo
npm run test:share
npm run test:jsonld
npm test
Für Playwright lokal:
npx playwright install chromium
4. Hosting, Domain und Serverfrage
Haben wir einen eigenen Server?
Für die statische Website nein; für Formulare ja.
GitHub Pages liefert die Website aus. Kontakt- und Exposé-POSTs gehen an den vorhandenen VPS unter forms.digitalisierungsplanung.de. Dort terminiert Nginx TLS und routet ausschließlich die Formularpfade an dp-forms.service auf Loopback-Port 8791. Es gibt weiterhin keine eigene Formular-Datenbank.
Wo liegt die Website?
Die Dateien liegen im GitHub-Repository und werden von GitHub Pages statisch ausgeliefert.
Die Datei:
CNAME
enthält:
immobilieneichmann.de
Damit ist die Custom Domain der GitHub-Pages-Site zugeordnet.
Die DNS-Konfiguration selbst liegt außerhalb dieses Repositories beim jeweiligen DNS-Provider. Das Repository enthält keine Zugangsdaten zum DNS-Provider.
Was passiert bei einem normalen Seitenaufruf?
- DNS löst
immobilieneichmann.deauf GitHub Pages auf. - GitHub Pages liefert fertige statische Dateien aus.
- Der Browser führt
cookie-consent.jsundmain.jsaus. - Nur beim Absenden eines Kontakt-/Exposé-Formulars wird
forms.digitalisierungsplanung.deaufgerufen. - Drittanbieter werden nur für die jeweils beschriebenen Funktionen aufgerufen.
5. Verzeichnisstruktur
/
├── .github/workflows/ GitHub-Actions-Automation
├── admin/ statisches Exposé-Admin
├── assets/
│ ├── flyer/ Flyerbilder
│ ├── listings/ lokal gespeicherte Objektbilder
│ ├── logo* Marken-/Header-Assets
│ └── share-card* Social-Preview-Bilder
├── css/styles.css gesamtes Public Styling
├── data/listings.json generierter lokaler Spiegel der Immowelt-Objektdaten
├── js/
│ ├── main.js
│ ├── cookie-consent.js
│ └── analytics.js
├── objekt/*.html generierte Objekt-/Exposé-Seiten
├── partials/ generierte HTML-Fragmente
├── scripts/ Generatoren, Importer und Tests
├── index.html Startseite
├── kontakt.html allgemeines Kontaktformular
├── impressum.html
├── datenschutz.html
├── widerrufsbelehrung.html
├── vertrag-widerrufen.html
├── sitemap.xml
├── robots.txt
├── llms.txt
├── CNAME
├── .nojekyll
├── package.json
└── package-lock.json
6. Single Source of Truth für Immobilien
Die fachliche Single Source of Truth ist Immowelt. Helmut pflegt dort Titel, Preis, Status, Referenznummern und Objektdaten.
data/listings.json ist ausschließlich der lokale, generierte Spiegel für Rendering und Website-Betrieb. Als lokale Abweichung ist nur site_hidden erlaubt: damit kann ein Immowelt-Objekt auf der eigenen Website ausgeblendet werden, ohne Immowelt zu verändern.
Top-Level-Struktur:
{
"sot": "local",
"source": "...",
"immowelt_profile": "...",
"scraped_at": "...",
"listing_count": 13,
"listings": []
}
Typische Felder eines Listings:
idsluglocal_urltitlepricelocationroomsliving_areaplot_areatypestatusshort_descriptiondescriptionfactsexpose_urlmain_image_urlimagesfloor_plansimage_basegallery_basesfloor_plan_basessourceimmowelt_idsync_policymissing_on_immoweltactive– steuert, ob ein Objekt öffentlich erscheint;falsebehält es intern, veröffentlicht es aber nichtdetail_page–falseerlaubt einen öffentlichen Kontakt-Teaser ohne erfundene Exposé-Inhalte; nurtrueerzeugt Detailseite und Sitemap-Eintrag- optional
manual_overrides
Die HTML-Seiten unter objekt/, die Karten auf Start-/Projektseite und die Objekt-URLs in sitemap.xml werden daraus erzeugt.
7. Immowelt-Import
Immowelt ist nur eine externe Inbound-Quelle.
Das Immowelt-Konto wird von dieser Codebasis niemals beschrieben.
Quelle:
https://www.immowelt.de/profil/3b18336c6a2e401da38e9cc20268270d
Importer:
scripts/sync-immowelt.mjs
Workflow:
.github/workflows/sync-immowelt.yml
Ablauf eines normalen Full-Syncs
- GitHub Actions startet einen kurzlebigen Ubuntu-Runner.
- Node 20 und Dependencies werden installiert.
- Playwright Chromium öffnet das öffentliche Immowelt-Profil.
- Öffentliche Objektinformationen werden gelesen.
- Soweit möglich werden Detailseiten für Beschreibung, Bilder, Grundrisse und Fakten angereichert.
- Neue Daten werden gegen
data/listings.jsongemerged. - Objektbilder werden heruntergeladen.
- Sharp erzeugt lokale JPG-/WebP-Versionen.
- JSON wird aktualisiert.
- Karten, Exposé-Seiten und Sitemap werden neu gerendert.
- Geänderte Dateien werden auf
maincommitted. - GitHub Pages deployed den neuen Stand.
Zeitplan
Der Workflow läuft regulär:
0 */3 * * *
also alle drei Stunden nach UTC.
Zusätzlich kann er manuell gestartet werden.
Wenn scripts/sync-immowelt.mjs oder der Workflow selbst geändert wird, wird auf Push nur aus dem vorhandenen kanonischen JSON gerendert, damit Templateänderungen ohne erneuten Live-Scrape sofort auf alle Objektseiten kommen.
DataDome / Bot-Schutz
Immowelt kann automatisierte Browser mit DataDome/Captcha blockieren.
Darum ist der Import bewusst als Soft-Fail gebaut:
- bei Scrape-Fehlern bleibt das zuletzt gültige JSON erhalten
- die öffentliche Site wird nicht leergeräumt
- kein Login und kein Captcha-Bypass
- das Immowelt-Konto wird nicht verändert
Merge-Regeln
Standard:
sync_policy = independent
Bedeutung:
- neue Immowelt-ID -> kann lokal ergänzt werden
- vorhandene Objekte -> nur nicht manuell geschützte Felder werden aktualisiert
manual_overrides[field] = trueschützt einen Wert vor Immowelt-Überschreibensource: localist lokal autoritativ- auf Immowelt verschwundene Objekte werden standardmäßig nicht automatisch gelöscht
- stattdessen
missing_on_immowelt: true - nur
sync_policy: mirrorerlaubt Auto-Entfernung eines verknüpften, dort verschwundenen Objekts
8. Bilder
Objektbilder liegen persistent im Git-Repository:
assets/listings/
Der Importer erzeugt in der Regel:
- JPG für breite Kompatibilität
- WebP für kleinere Übertragung
- separate Gallery-Dateien
- separate Grundriss-Dateien
Sharp übernimmt die Konvertierung.
Nicht mehr referenzierte, vom System verwaltete Objektbilder werden beim Rendern/Sync als Orphans erkannt und aufgeräumt.
Admin-Uploads werden zuerst per GitHub Contents API als Datei committed und danach in data/listings.json referenziert. Das ist ein zweistufiger Vorgang, keine Datenbanktransaktion.
9. Exposé-Anfrageflow
Referenz: bi-bodenseeimmo
Der öffentliche Exposé-Flow von:
https://www.bi-bodenseeimmo.de/
wurde am 20.09.2026 gegen aktuelle Objektseiten geprüft.
Die sichtbaren Personen-/Adressfelder des Eichmann-Exposé-Flows entsprechen diesem Referenzflow:
- Anrede* – Select
- Vorname*
- Name*
- Straße und Hausnummer*
- PLZ*
- Ort*
- Telefonnummer – optional
- E-Mail-Adresse*
Auf Eichmann-Exposé-Seiten gibt es bewusst kein zusätzliches Freitext-Nachrichtenfeld.
Die bi-bodenseeimmo-Seite zeigt zusätzlich eine Datenschutz-Einwilligungscheckbox. Diese wird hier bewusst nicht kopiert: die Eichmann-Site verwendet für die notwendige Anfragebearbeitung einen Datenschutzhinweis mit Link statt einer zusätzlichen Pflicht-Einwilligung.
Generiert wird der Flow zentral in:
scripts/sync-immowelt.mjs
Dadurch gelten Änderungen automatisch für alle erzeugten Objektseiten.
Versteckte technische Felder
Zusätzlich zu den sichtbaren Feldern werden Objektkontext und Mail-Metadaten mitgegeben:
anliegen = Exposé-Anfrageobjektobjekt_url- ein Honeypot-Feld
botcheck
Mail-Betreff und Empfänger werden serverseitig festgelegt; der Browser darf sie nicht frei bestimmen.
Validierung
js/main.js:
- trimmt Benutzereingaben
- nutzt die nativen HTML-
required-/E-Mail-Regeln - prüft mit
form.checkValidity() - zeigt Browserfehler via
reportValidity() - blockiert den clientseitigen Honeypot
- sendet erst dann
Damit ist eine komplett leere Exposé-Anfrage technisch nicht mehr möglich.
Regressionstest:
npm run test:expose-form
Der Test startet Chromium, lädt eine generierte Exposé-Seite, prüft Feldsatz, Reihenfolge, Required-Status, Payload und Success-UI und mockt ausschließlich die Netzwerkgrenze zum eigenen Formular-Gateway.
Serverseitige Trust-Grenze
Zusätzlich zur Browservalidierung validiert der Gateway die Pflichtfelder nochmals serverseitig. Er erzwingt Tenant, erlaubte Origins, feste Empfänger, feste Exposé-URL-Domain, Requestgrößen und Rate-Limits. Erfolg wird erst gemeldet, nachdem Amazon SES den Versand angenommen hat.
10. Allgemeines Kontaktformular
kontakt.html ist vom Exposé-Flow getrennt.
Pflichtfelder:
- Name
- Nachricht
Optional:
- Telefon
- Betreff/Anliegen-Auswahl
Auch hier:
- Whitespace wird entfernt
- native Validierung läuft
- komplett leere Anfragen werden blockiert
- kein Datenschutz-Pflicht-Haken
- Datenschutzhinweis mit Link
- Hinweis: durch Absenden kommt kein Maklervertrag zustande
11. Wie E-Mails tatsächlich verschickt werden
Produktiver Pfad:
Browser auf immobilieneichmann.de
-> HTTPS JSON POST
-> https://forms.digitalisierungsplanung.de/v1/immobilieneichmann/{contact|expose}
-> Nginx
-> dp-forms.service (127.0.0.1:8791)
-> Amazon SES
-> info@immobilien-eichmann.com
Der Gateway ist vom Hauptprodukt digitalisierungsplanung.de getrennt: eigener systemd-Dienst, eigener Linux-User, eigene Environment-Datei, eigener Loopback-Port, keine gemeinsame Account-Datenbank und keine Produktsession.
Bei Erfolg antwortet er mit:
{ "success": true, "requestId": "…" }
Bei Fehler zeigt die Website die bestehende Fehlerbox und den Mailto-Fallback. Die HTML-Formulare besitzen zusätzlich ein normales action auf denselben Gateway und method="POST" als einfachen No-JavaScript-Fallback.
Speicherung und Logs
Kontakt-/Exposé-Eingaben werden nicht in dieses GitHub-Repository, Local Storage, Session Storage oder eine eigene Formular-Datenbank geschrieben. Der Gateway verarbeitet sie im Arbeitsspeicher für Validierung und Mailversand. Seine technischen Logs enthalten Request-ID, Tenant, Flow, Status und Dauer, aber keine Formularinhalte oder Kontaktdaten. Danach liegt die Anfrage als E-Mail im Zielpostfach info@immobilien-eichmann.com, abhängig von dessen Aufbewahrungseinstellungen.
GitHub Pages hostet die Website, nicht das E-Mail-Postfach. Der Versand erfolgt über Amazon SES; die konkrete Mailbox-/MX-Infrastruktur von immobilien-eichmann.com wird weiterhin nicht in diesem Repository konfiguriert.
12. Datenschutz- und Consent-Runtime
Consent-Code:
js/cookie-consent.js
Browser-Key:
eichmann_cookie_consent_v1
Gespeichert wird in localStorage:
{
"necessary": true,
"analytics": false,
"ts": 0
}
Es wird also nur die Consent-Entscheidung lokal im Browser gespeichert.
Google Analytics
Analytics wird nicht beim ersten Seitenaufruf automatisch geladen.
Nur wenn der Nutzer „Alle akzeptieren“ wählt:
cookie-consent.jslädtjs/analytics.jsanalytics.jslädt Googlesgtag.js- GA4 startet mit Measurement ID
G-QVRRBPYNVM
Ohne Analytics-Consent wird googletagmanager.com von unserer Analytics-Logik nicht geladen.
Google Fonts
Keine externen Google Fonts.
Die Website verwendet lokale/System-Font-Stacks. Dadurch entsteht beim normalen Rendern kein Fonts-Request an Google.
Google Maps
Es gibt keinen automatisch geladenen Maps-Iframe.
Auf der Kontaktseite gibt es nur einen externen Link. Erst wenn der Nutzer ihn anklickt, wird Google Maps geöffnet.
13. Admin-System
URL:
https://immobilieneichmann.de/admin/
Unified UI (tabs: Immowelt | Eigen-Inserate). /admin/eigen/ redirects to /admin/#eigen.
Details: admin/README.md and docs/STABSCHEF-admin-unified-2026-09-25.md.
Login-Modus
admin/config.json:
auth_mode = password_session
Login benötigt:
- freigeschaltete E-Mail-Adresse
- Admin-Passwort
Kein GitHub-PAT. Der Browser ruft POST /admin/api/login auf; nginx proxyt auf 127.0.0.1:3847.
Die API prüft Allowlist + password_sha256 und setzt ein HttpOnly Secure SameSite=Strict Cookie.
Speichern
Browser → /admin/api/{eigen|visibility|publish}
→ eichmann-admin-api (systemd)
→ SQLite SoT → publish-from-db → /var/www/…
Immowelt-Konto bleibt read-only. Immowelt-Import weiterhin über sync-immowelt.yml.
Entfernt (2026-09-25)
- Sitzungs-PAT /
sessionStorageToken admin-eigen-save.yml(repository_dispatch→ SSH upsert)- Standalone Eigen-UI (nur Redirect)
14. Admin-Speicherflow (Legacy / GitHub Contents — deprecated)
Deprecated 2026-09-25: Day-to-day CRUD uses
/admin/api/on the droplet. The flows below describe the old PAT + Contents API path and may still apply to leftoveradmin-save.ymltooling.
Objekt bearbeiten
Primärer Pfad:
Admin-Browser
-> GET data/listings.json + SHA über GitHub Contents API
-> Benutzer ändert Felder
-> PUT data/listings.json mit bisherigem SHA
-> GitHub Commit
-> repository_dispatch admin_apply_render
-> GitHub Action rendert
-> Commit generierte Outputs
-> GitHub Pages Deployment
Die Verwendung des aktuellen File-SHA ist eine einfache Form von Optimistic Concurrency: ein offensichtlich veralteter Stand kann von GitHub mit Konflikt abgewiesen werden.
Fallback
Wenn der direkte Contents-API-Save fehlschlägt:
repository_dispatch: admin_save_listings
Dann schreibt admin-save.yml die komplette vom Browser gesendete JSON-Datei und rendert anschließend.
Dieser Fallback ist funktional, aber keine transaktionale Multi-User-Datenbank. Gleichzeitiges Bearbeiten durch mehrere Admins sollte vermieden werden.
Neues Objekt
Das Admin erzeugt:
- neue UUID
- stabilen Slug
- lokalen Datensatz
source: localsync_policy: independentmanual_overridesfür manuell gepflegte Felder
Eine optionale Immowelt-URL/UUID kann als Inbound-Verknüpfung hinterlegt werden.
Löschen
Löschen entfernt den Datensatz aus data/listings.json.
Der anschließende Render entfernt:
- die nicht mehr benötigte
objekt/{slug}.html - systemverwaltete orphaned Bilder, soweit sie nicht mehr referenziert sind
- die Objekt-URL aus der Sitemap
Foto-Upload
- Browser liest die Datei als Base64.
- GitHub Contents API committed die Datei nach
assets/listings/. - Das Listing bekommt die neue Bildreferenz.
data/listings.jsonwird committed.- Render läuft.
Maximale vom Admin akzeptierte Uploadgröße: ungefähr 4,5 MB.
Erlaubte Dateitypen im aktuellen Adminpfad:
- JPG/JPEG
- PNG
- WebP
15. Manuelle Overrides
Wird ein Feld im Admin manuell verändert, schreibt das Admin:
"manual_overrides": {
"title": true,
"price": true,
"updated_at": "..."
}
Der Immowelt-Importer respektiert diese Locks.
Geschützte Feldgruppen umfassen unter anderem:
- Titel
- Preis
- Ort
- Zimmer
- Wohn-/Grundstücksfläche
- Typ
- Status
- Kurzbeschreibung
- Beschreibung
- Bilder/Gallery
- Grundrisse
- Fakten
- Hauptbild
So bleibt lokal gepflegter Inhalt autoritativ.
16. GitHub-Actions-Pipelines
sync-immowelt.yml
Aufgabe:
- regelmäßiger öffentlicher Immowelt-Import
- manueller Sync
- Render-only
- Generatoränderungen auf Push neu ausrollen
Schreibziel:
data/listings.jsonassets/listings/partials/listings-grid.htmlindex.htmlprojekte.htmlobjekt/sitemap.xml
admin-save.yml
Aufgabe:
- Admin-
repository_dispatchempfangen - JSON speichern oder nur rendern
- generierte Outputs committen
- optional Immowelt-Workflow anstoßen
Events:
admin_save_listingsadmin_apply_renderadmin_trigger_sync
apply-legal-baseline.yml
Wird ausgeführt, wenn die Legal-Baseline selbst geändert wird.
Ablauf:
- Baseline anwenden
- Legal-/Privacy-Regressionsprüfung
- Dependencies installieren
- Playwright installieren
- Layout prüfen
- Änderungen gegebenenfalls committen
layout-regression.yml
Hard Gate für relevante Frontendänderungen.
Prüft:
- Legal-/Privacy-Baseline
- Exposé-Formular-Feldsatz und Payload
- Desktop-Layout
- Mobile-Layout
- Horizontal Overflow
- Header/Logo
- Flyer-Geometrie
- Kontaktformular kann leer nicht absenden
Screenshots werden als GitHub-Actions-Artefakt hochgeladen.
logo-consistency.yml
Prüft Logo-Dateien, Versionierung und bekannte Fehlerbilder.
Der Logo-Test selbst läuft aktuell standardmäßig soft; die Header-Logo-Sicherheitsversion ist:
assets/logo-header.svg?v=header-safe-v1
Der zusätzliche rechte SVG-Viewport verhindert, dass das letzte N im Header wieder abgeschnitten wird.
share-card.yml
Auf jedem Push/PR:
npm run test:share
Prüft unter anderem:
- 1200 × 630
- JPEG
- Dateigröße
- korrekte OG-/Twitter-Referenzen
- keine Abweichung vom freigegebenen Plain-Bild
refresh-share-card.yml
Nur bei Änderungen am Refresh-Script/Workflow.
Lädt das freigegebene Immobilienbild, erzeugt 1200 × 630 und schreibt:
share-card-source-plain-v2.jpgshare-card-plain-v2.jpg- Legacy-Dateien
Es werden kein Text und kein Logo-Overlay hinzugefügt.
GitHub Pages Deployment
Das Pages-Build-/Deploy ist ein GitHub-eigener Workflow und liegt deshalb nicht zwingend als eigene YAML-Datei in diesem Verzeichnis.
Jeder relevante Commit auf main wird anschließend über GitHub Pages veröffentlicht.
17. Tests
Gesamtsuite
npm test
Einzeltests
npm run test:share
npm run test:logo
npm run test:jsonld
npm run test:legal
npm run test:layout
npm run test:expose-form
Legal-/Privacy-Test
scripts/test-legal-baseline.mjs prüft unter anderem:
- keine externen Google Fonts
- kein automatisch eingebettetes Google Maps
- keine ausgeschaltete native Formvalidierung
- keine Legal-Platzhalter
- keine unnötige Datenschutz-Pflichtcheckbox
- Impressumsbehörde vorhanden
- Datenschutz nennt reale eingesetzte Dienste
- Widerruf enthält 14-Tage-Regel und keine alte 30-Tage-Fassung
- generierte Objektseiten nutzen Consent-Gate
- Header-Logo-Sicherheitsversion bleibt erhalten
Exposé-Flow-Test
Shortened here. Read the whole README on GitHub.
Tools it offers (5)
What this server listed when ahel dialed its public endpoint in Oct 2026, with no key and no account of yours. The names are the server’s own.
search_listingsget_listingget_flyerget_contactsubmit_inquiry
Signals
- Last commit
- Oct 2026
Advanced
- Delivery
- listings MCP server → your ahel connector (mcp.ahel.ai) → your AI.
- Item type
- mcp-server
- Key
de-immobilieneichmann-listings- Source
- github.com/christianhohlfeld/eichmannimmobilien
- Hosted endpoint
https://immobilieneichmann.de/mcp
github.com/christianhohlfeld/eichmannimmobilien