Laravel MCP-Server für SparkSpot: Warum unser ChatGPT-Agent nur suchen darf

Laravel MCP-Server für SparkSpot: Warum unser ChatGPT-Agent nur suchen darf

Ein Autofahrer in Brüssel fragt ChatGPT, wo er morgen Nachmittag in Bahnhofsnähe parken kann. Zurück kommen ein paar private Stellplätze, jeder mit Preis und Foto. Er tippt auf einen, landet auf dessen Seite auf der Website, die Daten sind schon eingetragen, und bezahlt dort.

Mehr ist es nicht. Das ist der komplette ChatGPT-Kanal, den wir für SparkSpot gebaut haben, einen belgischen Marktplatz, auf dem Privatleute ihre Einfahrten und Garagen an Autofahrer vermieten. Dahinter steht ein Laravel MCP-Server mit genau einem Tool, und dieses Tool sucht. Buchen, bezahlen, stornieren oder den Eigentümer sehen kann es nicht. Das war die wichtigste Designentscheidung im ganzen Projekt.

Wenn Sie gerade überlegen, Ihr Produkt für KI-Agenten zu öffnen, lautet mein Rat deshalb: Geben Sie dem Agenten den Teil Ihres Produkts, der liest. Alles, was Geld bewegt, bleibt auf einer Seite, auf der ein Mensch den Preis sieht, bevor er klickt.

Was SparkSpot brauchte

Der Marktplatz selbst lief. Eigentümer stellen ihre Stellplätze ein, Autofahrer buchen auf der Website, und eine mobile App ist in Arbeit. Gehakt hat es vorher, auf dem Weg zur ersten Buchung. Wer zum ersten Mal kommt, muss die Website finden oder die App herunterladen, ein Konto anlegen und sich in eine Oberfläche einarbeiten, die er noch nie gesehen hat. Alles für ein paar Stunden Parken.

Der Auftrag an uns war entsprechend knapp. Der Fahrer fragt ChatGPT, installiert nichts und braucht vorher kein Konto.

Was MCP ist und was schon da war

MCP steht für Model Context Protocol, einen Standard, über den ein KI-Assistent Funktionen Ihrer Software aufrufen kann. Sie beschreiben diese Funktionen als Tools. Jedes Tool hat einen Namen, eine Beschreibung in normaler Sprache und ein Eingabeschema, das festlegt, welche Felder in welchem Format erwartet werden. Wann ein Tool aufgerufen wird, entscheidet der Assistent selbst. ChatGPT-Apps laufen auf MCP, Integrationen für Claude ebenfalls.

Für Laravel gibt es dafür das offizielle Paket laravel/mcp. Wir haben im Januar 2026 mit Version 0.5.1 angefangen, in Produktion läuft heute 0.5.9. Im September 2026 ist Version 1.0 erschienen, passend zur neuen Protokollrevision aus dem Juli. Das Upgrade steht noch auf unserer Liste.

Das meiste, was wir brauchten, existierte schon vor dem ersten Gespräch. Hinter der Website von SparkSpot liegt eine öffentliche Such-API. Sie prüft Daten und Entfernungen, fragt die Suchmaschine Meilisearch nach Stellplätzen in der Nähe und berechnet, welche davon im gewünschten Zeitraum frei sind. Für ChatGPT mussten wir also keine neue Logik erfinden.

Die eigentliche Frage war eine andere: Wie viel vom Rest der API soll ein Agent überhaupt zu sehen bekommen?

Drei Wege, einen Marktplatz für KI-Agenten zu öffnen

Auf dem Tisch lagen drei Varianten.

  • Die komplette Buchung als Tools. Suchen, reservieren, bezahlen und stornieren, alles im Chat. Das gibt die beste Demo, ohne Frage. Es setzt aber eine Kontoverknüpfung per OAuth voraus, also ein Verfahren, bei dem sich der Fahrer bei SparkSpot anmeldet und dem Assistenten erlaubt, in seinem Namen zu handeln. Vorher kann der Agent für niemanden etwas tun. Danach kann er das Geld eines Fremden verbindlich ausgeben. Und Sie handeln sich eine neue Fehlerklasse ein: Das Modell bucht sehr höflich das Falsche.
  • Eine eigene, schlanke „KI-API“. Eine zweite Schnittstelle, auf das Modell zugeschnitten. Die muss mit der ersten synchron bleiben, und sie läuft auseinander, sobald zum ersten Mal eine Validierungsregel nur in einer der beiden geändert wird.
  • Nur Suche, dann Übergabe an die Website. Ein einziges lesendes Tool und ein Link zum selben Checkout, den jeder Besucher der Website auch benutzt.

Wir haben uns für die dritte Variante entschieden. Die erste war verlockend, gerade weil sie in einer Präsentation so gut aussieht. Aber eine Demo bucht keine Stellplätze für echte Menschen mit echten Kreditkarten.

Warum unser Laravel MCP-Server genau ein Tool hat

Ein Satz, auf den ich bei diesem Projekt immer wieder zurückkomme: Der Agent darf den Stellplatz finden und Sie hinführen. Geld und Verbindlichkeit bleiben dort, wo ein Mensch den Preis sieht und selbst auf „Bezahlen“ tippt.

Daraus ergaben sich fünf konkrete Entscheidungen.

Dieselbe Tür wie die Website. Das Tool baut intern eine Anfrage an dieselbe Route, die auch die Website aufruft, und schickt sie ab. Die Anfrage läuft damit durch denselben Controller, dieselbe Eingabeprüfung (in Laravel ein Form Request) und dieselbe Meilisearch-Abfrage. Jede Regel der Website gilt so automatisch auch für den Agenten. Das Startdatum darf nicht in der Vergangenheit liegen, das Enddatum nicht vor dem Startdatum. Ein Zeitraum darf höchstens 70 Tage umfassen, der Suchradius höchstens 100 km.

Schlägt die Prüfung fehl, reicht das Tool die Fehlermeldung der API an den Agenten weiter, und der bittet den Fahrer, seine Angaben zu korrigieren. Das Tool selbst validiert nichts. Eine zweite Kopie der Regeln wäre genau das Auseinanderlaufen gewesen, das wir mit dem Verzicht auf Variante zwei vermeiden wollten.

Genau 8 Felder, von Hand ausgewählt. Pro Stellplatz liefert das Tool ID, Name, Adresse, Entfernung, Durchschnittspreis, die Anzahl freier Plätze, ein Foto und die URL. Mehr nicht. Name und Kontaktdaten des Eigentümers verlassen den Server nie, die Anfahrtshinweise ebenso wenig. Den Zugangscode für das Tor bekommt der Fahrer erst nach einer bezahlten Buchung zu sehen, und auch dann nur auf der Website.

Annotationen, die sagen, was das Tool nicht tut. Mit laravel/mcp lässt sich ein Tool annotieren, also mit maschinenlesbaren Hinweisen versehen. Unseres ist als rein lesend markiert, als nicht destruktiv und als „closed world“, das heißt: Es greift auf nichts außerhalb unseres eigenen Systems zu. Clients wie ChatGPT können diese Hinweise auswerten, etwa um zu entscheiden, ob der Nutzer einen Aufruf vorher bestätigen muss. Vereinfacht sieht die Klasse so aus:

#[IsReadOnly]
#[IsDestructive(false)]
#[IsOpenWorld(false)]
class SearchParkingSpots extends Tool
{
    public function schema(JsonSchema $schema): array
    {
        return [
            'from' => $schema->string()
                ->description('First day of parking, YYYY-MM-DD. For a single day, use the same date in from and to. Never set to = from + 1.')
                ->required(),
            'to' => $schema->string()
                ->description('Last day of parking, inclusive, YYYY-MM-DD.')
                ->required(),
            // location and radius fields omitted
        ];
    }
}

Ein öffentlicher Endpunkt, mit Absicht. Es gibt keinen Login. Wir haben die Route bewusst aus der OAuth-Konfiguration herausgelassen, deshalb fordert ChatGPT den Fahrer nie auf, sich anzumelden. Das ist nur vertretbar, weil das Tool öffentliche Inserate liest und sonst gar nichts. Im selben Laravel-Backend laufen 2 interne MCP-Server für das Admin-Team, und die sind abgesichert, mit Sanctum-Tokens oder Passport-OAuth (beides Laravel-Pakete für die Authentifizierung) und mit einem eigenen Scope, also einem eigenen Berechtigungsbereich, pro Server.

Die Übergabe ist ein Link. Ein Tipp auf die Karte öffnet die Seite des Stellplatzes auf der Website, die Daten sind vorausgefüllt. Von dort geht es in denselben Stripe-Checkout, den jeder andere Besucher auch sieht, Buchung als Gast eingeschlossen. Das Backend weiß nicht, dass der Fahrer aus ChatGPT kommt. Es muss das auch nicht wissen.

Was trotzdem schiefging: „morgen“ ist ein Tag

Der Fehler, der uns wirklich wehgetan hat, hatte weder mit Sicherheit noch mit dem Protokoll zu tun. Es ging um die Frage, was ein Datum bedeutet.

Ein Fahrer schreibt „morgen parken“ oder „am 22. April“. Das Modell denkt dabei wie bei einer Hotelbuchung und schickt 22. April bis 23. April, also eine Nacht. SparkSpot zählt Tage aber inklusive. Ein einzelner Tag ist hier der 22. April bis zum 22. April. Der Agent hatte damit 2 Tage angefragt.

Das hatte zwei Folgen. Die Verfügbarkeitsprüfung lief über 2 Tage, und ein Stellplatz, der nur am 22. frei war, verschwand aus den Ergebnissen, weil das Tool nur Plätze behält, die über den gesamten Zeitraum verfügbar sind. Die zweite Folge war schlimmer. Der Link auf der Karte trug die Daten des Agenten weiter, und die Website öffnete eine Buchung über 2 Tage, zum doppelten Preis.

Aufgefallen ist uns das in Nightwatch, einem Monitoring-Tool, das jede Anfrage an die MCP-Route aufzeichnet.

Die Korrektur ging am 25. Februar 2026 live, und sie bestand aus Text. Die Regel, dass ein einzelner Tag dasselbe Datum in beiden Feldern bedeutet und niemals from plus eins, steht jetzt an drei Stellen: in der Beschreibung des Tools, in den Beschreibungen der Felder from und to im Schema und im Prompt find-parking. Das Widget, also die Kartenansicht im Chat, zeigt außerdem nur noch ein einzelnes Datum, wenn from und to gleich sind. So sieht der Fahrer, wie der Agent seine Anfrage verstanden hat. Seit Februar gibt das Tool in seiner strukturierten Antwort zusätzlich die Daten zurück, mit denen es tatsächlich gesucht hat.

Auf dem Server abgelehnt haben wir solche Anfragen nicht, und wir hätten es auch nicht gekonnt. Eine echte Buchung über 2 Tage, vom 22. bis zum 23., sieht genauso aus wie die versehentliche. Der Fehler steckt in der Bedeutung, nicht im Format, und so etwas fängt keine Validierungsregel ab. Die beste Verteidigung besteht darin, dem Menschen die Deutung des Agenten zu zeigen, bevor er bezahlt.

Seitdem sehe ich Tool-Beschreibungen anders. Für einen Agenten sind sie keine Dokumentation, sie sind die Schnittstelle selbst. Ein vager Satz darin ist ein Fehler in Ihrem API-Vertrag.

Wohin die Stunden tatsächlich gingen

Die meisten Stunden haben wir nicht in MCP gesteckt. Sie gingen in die Regeln, die ChatGPT für das Karten-Widget vorgibt.

Ein Beispiel: Die Content Security Policy des Widgets, also die Liste der Domains, von denen es Inhalte laden darf, ging davon aus, dass die Fotos auf der Domain der App selbst liegen. In Produktion kommen sie aber aus dem CDN von DigitalOcean Spaces. ChatGPT hat sie blockiert, und jede Karte zeigte nur ein kaputtes Bild.

Mit derselben Korrektur haben wir auch eine Icon-Bibliothek auf eine feste Version gesetzt. Sie wurde vorher über ein „schwebendes“ Versions-Tag geladen, das immer auf die jeweils neueste Ausgabe zeigt. Ein Release, auf das wir keinen Einfluss haben, hätte das Widget damit lahmlegen können, ohne ein einziges Deployment auf unserer Seite und ohne jede Spur in unseren Logs.

Das sind Probleme von ChatGPT, nicht vom Protokoll. Und genau dieser Teil steht in keinem Tutorial.

Was ich heute anders machen würde

Zwei Dinge, beide klein und beide im Nachhinein ärgerlich.

  • Den Suchdienst direkt aufrufen. Die interne HTTP-Anfrage über den Router hat die Regeln zwar an einer Stelle gehalten. Dafür sah in den Logs und Request-Details jeder Aufruf so aus, als käme er vom Server selbst. Ruft das Tool den Dienst direkt auf, gelten dieselben Regeln, und die Verwirrung entfällt.
  • Die Sprache des Fahrers respektieren. Der Link öffnet die niederländische Version der Website. Wer in Brüssel auf Französisch fragt, landet also auf einer niederländischen Seite.

Ihr eigener Laravel MCP-Server: Womit Sie anfangen

Fangen Sie mit einer Frage an: Welchen Teil Ihres Produkts kann ein Agent benutzen, ohne dass jemand zu Schaden kommt, wenn er etwas falsch versteht? Bei den meisten Unternehmen sind das Suche, Nachschlagen und Statusabfragen.

Genau diese Teile gehören hinter einen Laravel MCP-Server. Wenn Ihr Backend ohnehin auf Laravel läuft, haben Sie mit laravel/mcp den kürzesten Weg dorthin; warum wir für solche Backends Laravel wählen, haben wir an anderer Stelle beschrieben. Schicken Sie jeden Aufruf durch den Code, dem Ihre Website schon vertraut, und lassen Sie Zahlungen und Zusagen auf einer Seite, die ein Mensch liest. Schreibende Tools können später kommen, wenn Sie gesehen haben, wie Agenten tatsächlich mit Ihrem System sprechen.

Dieselbe Regel gilt bei uns im eigenen Haus. Mit unserem Strapi-MCP-Server für den Blog entwirft der Agent, und ein Mensch veröffentlicht.

ChatGPT-Apps, MCP-Server und Claude-Integrationen auf bestehenden Laravel-Backends gehören zu unseren Leistungen im Bereich KI und Automatisierung. Wir fangen dabei nicht bei einem leeren Blatt an, sondern bei Ihrem vorhandenen Code, Ihren Routen und der Validierung, die Ihre Website heute schon nutzt. Wenn Sie überlegen, Ihr Produkt für ChatGPT oder Claude zu öffnen, schreiben Sie uns an [email protected].

#Laravel#MCP#ChatGPT-Apps#KI Entwicklung#Backend Entwicklung

Häufig gestellte Fragen

Was ist ein Laravel MCP-Server?

Eine Laravel-Anwendung, die einige ihrer Funktionen als Tools beschreibt, die ein KI-Assistent über das Model Context Protocol (MCP) aufrufen kann. Dafür gibt es das offizielle Paket laravel/mcp. Jedes Tool hat einen Namen, eine Beschreibung in normaler Sprache und ein Eingabeschema, und ChatGPT oder Claude entscheiden selbst, wann sie es aufrufen.

Sollte ein KI-Agent Buchungen oder Zahlungen auslösen dürfen?

In einer ersten Version aus unserer Sicht nicht. Der Agent bei SparkSpot sucht nur; Buchung und Bezahlung laufen auf der Website, wo der Fahrer den Preis sieht, bevor er bezahlt. Schreibende Tools lassen sich später ergänzen, wenn Sie wissen, wie Agenten mit Ihrem System umgehen.

Braucht ein öffentlicher MCP-Server eine Authentifizierung?

Nur wenn seine Tools private Daten berühren oder etwas verändern. Das Tool von SparkSpot liest ausschließlich öffentliche Inserate, deshalb ist der Endpunkt offen und verlangt keinen Login. Unsere internen MCP-Server für das Admin-Team sind dagegen per Sanctum-Token oder Passport-OAuth geschützt, mit einem eigenen Scope pro Server.

Wie verhindert man, dass ein KI-Agent Datumsangaben falsch versteht?

Eine Validierung auf dem Server fängt das nicht ab, weil ein falscher Zeitraum genauso aussehen kann wie ein echter. Schreiben Sie die Regel in die Beschreibung des Tools und der einzelnen Felder, geben Sie die tatsächlich verwendeten Daten in der Antwort zurück und zeigen Sie sie dem Menschen, bevor er bezahlt.

Kann Conimex IT einen MCP-Server für unsere Laravel-Anwendung bauen?

Ja. Wir bauen MCP-Server, ChatGPT-Apps und Claude-Integrationen auf bestehenden Laravel-Backends und setzen dabei auf dem Code und der Validierung auf, die Ihre Anwendung schon hat. Schreiben Sie uns an [email protected].

Haben Sie ein Projekt im Sinn?

Lassen Sie uns darüber sprechen, wie Conimex IT Ihnen helfen kann, Ihr nächstes Produkt zu gestalten, zu entwickeln und zu veröffentlichen.

Kontakt aufnehmen