Laravel MCP server sa jednim alatom: kako smo SparkSpot doveli u ChatGPT

Laravel MCP server sa jednim alatom: kako smo SparkSpot doveli u ChatGPT

Vozač u Briselu pita ChatGPT gde može da parkira blizu stanice sutra posle podne. Dobija nekoliko privatnih mesta, svako sa cenom i fotografijom. Dodirne jedno, otvori mu se stranica tog mesta na sajtu sa već upisanim datumima i tamo plati.

To je ceo ChatGPT kanal koji smo napravili za SparkSpot, belgijsku platformu na kojoj vlasnici privatnih parking mesta izdaju ta mesta vozačima. Iza njega stoji Laravel MCP server sa tačno jednim alatom. Taj alat pretražuje i ništa više: ne može da rezerviše, da naplati, da otkaže niti da vidi ko je vlasnik mesta. Upravo to ograničenje je najvažnija odluka u celom projektu.

Ako razmišljate da svoj proizvod otvorite AI agentima, odnosno asistentima kao što su ChatGPT i Claude, moj savet je kratak. Dajte agentu deo proizvoda koji čita. Sve što pomera novac neka ostane na stranici na kojoj čovek vidi cenu pre nego što klikne.

Šta je SparkSpotu trebalo

SparkSpot povezuje ljude koji imaju slobodan prilaz ispred kuće ili garažu sa vozačima kojima treba mesto za parkiranje. Platforma je već radila kako treba: vlasnici objavljuju svoja mesta, vozači ih rezervišu na sajtu, a mobilna aplikacija je bila u izradi.

Zapinjalo je na putu do prve rezervacije. Vozač koji samo želi da ostavi kola na nekoliko sati morao je da pronađe sajt ili preuzme aplikaciju, napravi nalog i snađe se u interfejsu koji vidi prvi put. Previše koraka za jedno parkiranje. Zato je zadatak koji smo dobili glasio ovako: vozač pita ChatGPT, ništa ne instalira i ne pravi nalog pre nego što vidi šta mu se nudi.

Šta je MCP i šta smo zatekli u kodu

MCP (Model Context Protocol) je standardni način na koji AI asistent poziva Vaš softver. Vi opisujete alate, a svaki alat ima ime, opis napisan običnim jezikom i šemu ulaznih podataka, to jest spisak polja koja alat prima. Asistent sam odlučuje kada će koji alat da pozove. Na ovom protokolu rade ChatGPT aplikacije, a na njemu rade i integracije za Claude.

Za Laravel postoji zvanični paket laravel/mcp. Počeli smo na verziji 0.5.1 u januaru 2026, a danas radimo na verziji 0.5.9. Verzija 1.0, usklađena sa novom revizijom protokola iz jula, izašla je u septembru 2026. Prelazak na nju nam je još na spisku obaveza.

Najbolja vest bila je ono što je već postojalo. Iza sajta je radio javni API za pretragu koji proverava datume i udaljenosti, preko Meilisearch pretrage nalazi mesta u blizini i računa dostupnost za traženi period. Za ChatGPT nismo morali ništa da izmišljamo. Pravo pitanje bilo je drugačije: koliki deo ostatka API-ja uopšte pokazati agentu?

Tri načina da se platforma otvori agentu

Na stolu su bile tri opcije.

  • Ceo tok rezervacije kao alati. Pretraga, rezervacija, plaćanje i otkazivanje, sve u razgovoru sa ChatGPT-jem. Od toga bi ispao najlepši demo. Međutim, pre nego što agent bilo šta uradi u nečije ime, potrebno je povezati naloge preko OAuth-a, standardnog postupka kojim korisnik dozvoljava aplikaciji da radi u njegovo ime. Agent tada može da potroši novac čoveka kog nikad niste videli, a dobijate i potpuno novu vrstu greške: model koji ljubazno rezerviše pogrešnu stvar.
  • Poseban, sveden „AI API“. Drugi API, skrojen po meri modela. To znači dva API-ja koja moraju stalno da ostanu usklađena, a ona se razilaze onog trenutka kada se neko pravilo validacije promeni samo na jednom mestu.
  • Samo pretraga, pa prelazak na sajt. Jedan alat koji čita podatke i link ka istoj stranici za plaćanje koju koristi svaki posetilac sajta.

Izabrali smo treću opciju.

Zašto naš Laravel MCP server ima samo jedan alat

Rečenica kojoj se stalno vraćam glasi ovako: agent može da pronađe mesto i dovede Vas do njega, ali novac i obaveza ostaju na stranici na kojoj čovek vidi cenu i sam klikne „Plati“. Sve ostalo u ovom projektu proizlazi iz toga.

Ista vrata kao sajt. Alat sastavlja interni zahtev ka istoj ruti koju koristi sajt i prosleđuje ga aplikaciji. Taj zahtev prolazi kroz isti kontroler, istu validaciju (Laravel form request) i isti Meilisearch upit. Zato pravila sajta automatski važe i za agenta: početni datum ne sme biti u prošlosti, krajnji datum ne sme biti pre početnog, period može trajati najviše 70 dana, a poluprečnik pretrage može biti najviše 100 km. Kada validacija ne prođe, alat agentu vraća poruku o grešci koju je dao API, a agent zamoli vozača da ispravi unos. Sam alat ne proverava ništa. Druga kopija pravila bila bi upravo ono razilaženje koje smo hteli da izbegnemo.

8 polja, izabranih ručno. Za svako mesto agent dobija identifikator, naziv, adresu, udaljenost, prosečnu cenu, broj slobodnih mesta, fotografiju i URL. Sve ostalo smo izbacili. Ime i kontakt vlasnika nikad ne napuštaju server, kao ni uputstva za dolazak. Šifra za kapiju pojavljuje se tek posle plaćene rezervacije i samo na sajtu.

Anotacije koje klijent razume. Paket laravel/mcp dozvoljava da alat obeležite anotacijama, kratkim oznakama koje opisuju kako se alat ponaša. Naš alat nosi tri anotacije: samo čita, ništa ne uništava i radi u „zatvorenom svetu“, što znači da ne dopire ni do čega van našeg sistema. Klijenti, odnosno aplikacije poput ChatGPT-ja koje pozivaju server, mogu da koriste te anotacije, na primer kada odlučuju da li pre poziva treba tražiti potvrdu korisnika. U pojednostavljenom obliku kod izgleda ovako:

#[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
        ];
    }
}

Javna ruta, namerno. MCP ruta ne traži prijavu. Izostavili smo je iz OAuth podešavanja, pa ChatGPT nikad ne traži od vozača da se prijavi. To je moguće samo zato što alat čita javne oglase i ništa drugo. Na istom Laravel backendu rade i 2 interna MCP servera za administratorski tim. Oni su zaštićeni Sanctum tokenima ili Passport OAuth zaštitom, a svaki server ima svoj zaseban opseg ovlašćenja.

Prelazak na sajt je običan link. Kada vozač dodirne karticu, otvara se stranica tog mesta na sajtu sa već upisanim datumima. Odatle ide isto Stripe plaćanje kroz koje prolazi svaki posetilac sajta, uključujući rezervaciju bez naloga. Backend ne zna da je vozač stigao iz ChatGPT razgovora, niti ga to zanima.

Šta se ipak pokvarilo: „sutra“ je jedan dan

Greška koja nas je zaista zabolela nije imala veze ni sa bezbednošću ni sa protokolom. Ticala se toga šta znači datum.

Vozač napiše „parking sutra“ ili „22. april“. Model razmišlja kao da rezerviše hotel i šalje period od 22. do 23. aprila, jednu noć. SparkSpot, međutim, broji dane uključivo, pa jedan dan znači od 22. do 22. aprila. Agent je, dakle, tražio 2 dana.

Iz toga su nastala dva problema. Provera dostupnosti pokrivala je 2 dana, a alat zadržava samo mesta slobodna tokom celog perioda, pa je mesto slobodno samo 22. aprila ispadalo iz rezultata. Drugi problem bio je gori. Link na kartici nosio je agentove datume, pa je sajt otvarao rezervaciju za 2 dana po duplo višoj ceni.

Grešku smo uočili u Nightwatchu, alatu za praćenje koji beleži svaki zahtev ka MCP ruti. Ispravku smo pustili 25. februara 2026, a njen najvažniji deo bio je tekst. Pravilo „za jedan dan upiši isti datum u oba polja, nikad from + 1“ ponovili smo na 3 mesta: u opisu alata, u opisima polja from i to u šemi i u promptu find-parking, gotovom uputstvu koje server nudi asistentu. Vidžet, odnosno kartica sa rezultatima koju ChatGPT prikazuje u razgovoru, sada pokazuje jedan datum kada su from i to isti, pa vozač vidi kako je agent razumeo zahtev. Od februara alat u strukturiranom odgovoru vraća i datume koje je zaista pretražio.

Zašto takav zahtev nismo jednostavno odbili na serveru? Nismo mogli. Prava rezervacija za 2 dana, od 22. do 23. aprila, izgleda potpuno isto kao pogrešna. Greška je u značenju, a ne u formatu, pa je nijedno pravilo validacije ne hvata. Najbolja odbrana je da čovek pre plaćanja vidi kako je agent razumeo njegov zahtev.

Otad o opisima alata razmišljam drugačije. Opis alata nije dokumentacija. Za agenta on jeste interfejs, a nejasna rečenica u njemu je greška u ugovoru Vašeg API-ja.

Gde su zaista otišli sati

Najviše sati nije otišlo na MCP, već na pravila koja ChatGPT postavlja za vidžet sa karticama.

Evo primera. Politika bezbednosti sadržaja vidžeta (content security policy), odnosno spisak domena sa kojih vidžet sme da učitava sadržaj, podrazumevala je da su fotografije na domenu same aplikacije. Fotografije u produkciji, međutim, stoje na DigitalOcean Spaces CDN mreži, servisu koji isporučuje fajlove. ChatGPT ih je blokirao i svaka kartica prikazivala je polomljenu sliku. U istoj ispravci zaključali smo i verziju biblioteke ikonica, koja se do tada učitavala preko oznake verzije koja uvek pokazuje na najnovije izdanje. Tuđe izdanje moglo je da pokvari vidžet bez ijednog našeg puštanja nove verzije i bez traga u našim logovima.

To su problemi ChatGPT-ja, a ne protokola. Baš taj deo niko ne stavlja u tutorijal.

Šta bih danas uradio drugačije

Dve stvari, obe sitne, a gledano unazad obe pomalo iritantne.

  • Pozvao bih servis za pretragu direktno. Interni HTTP zahtev kroz ruter držao je pravila na jednom mestu, ali su zbog njega logovi i detalji zahteva izgledali kao da svaki poziv dolazi od samog servera. Kada alat direktno pozove servis, pravila su ista, a zabune ima manje.
  • Poštovao bih jezik vozača. Link otvara holandsku verziju sajta, pa vozač iz Brisela koji piše na francuskom završi na stranici na holandskom.

Kako da isplanirate sopstveni Laravel MCP server

Krenite od jednog pitanja: koji deo Vašeg proizvoda agent može da koristi a da niko ne nastrada ako ga pogrešno razume? Za većinu firmi to su pretraga, pronalaženje pojedinačnog zapisa i provera statusa.

Te delove stavite iza Laravel MCP servera i provucite ih kroz kod kome Vaš sajt već veruje. Plaćanja i obaveze ostavite na stranici koju čita čovek, a alate koji upisuju podatke dodajte kasnije, kada vidite kako agenti zaista razgovaraju sa Vašim sistemom. Ako Vam backend već radi na Laravelu, imate dobru polaznu tačku, a zašto za ovakve projekte biramo Laravel opisali smo u posebnom tekstu. Isto pravilo poštujemo i na sopstvenom Strapiju, gde agent piše nacrt, a članak objavljuje čovek.

ChatGPT aplikacije, MCP servere i integracije za Claude na postojećim Laravel backendima pravimo kao jednu od naših usluga. Ako razmišljate da svoj proizvod otvorite agentima, pišite nam na [email protected]. Polazimo od koda koji već imate, a ne od prazne stranice.

#Laravel#MCP#ChatGPT aplikacije#AI razvoj#Backend razvoj

Često postavljana pitanja

Šta je Laravel MCP server?

Laravel MCP server je Laravel aplikacija koja neke svoje funkcije opisuje kao alate koje AI asistent može da pozove preko protokola MCP (Model Context Protocol). Za to postoji zvanični paket laravel/mcp. Svaki alat ima ime, opis napisan običnim jezikom i šemu ulaznih podataka, a ChatGPT ili Claude sami odlučuju kada će koji alat da pozovu.

Da li AI agent treba da pravi rezervacije i naplaćuje?

Po našem mišljenju, ne u prvoj verziji. Agent za SparkSpot samo pretražuje, a rezervacija i plaćanje ostaju na sajtu, gde vozač vidi cenu pre nego što plati. Alate koji upisuju podatke ima smisla dodati kasnije, kada vidite kako agenti zaista koriste Vaš sistem.

Da li javnom MCP serveru treba autentifikacija?

Samo ako njegovi alati dodiruju privatne podatke ili nešto menjaju. Alat za SparkSpot čita javne oglase, pa je ruta otvorena i ne traži prijavu. Interni MCP serveri za administratorski tim zaštićeni su Sanctum tokenima ili Passport OAuth zaštitom, sa zasebnim opsegom ovlašćenja za svaki server.

Kako sprečiti da AI agent pogrešno protumači datume?

Validacija na serveru to ne može da uhvati, jer pogrešan period može da izgleda isto kao pravi. Pravilo napišite u opis alata i u opise polja, neka alat vrati datume koje je zaista koristio, a te datume pokažite korisniku pre nego što plati.

Može li Conimex IT da napravi MCP server za našu Laravel aplikaciju?

Može. Pravimo MCP servere, ChatGPT aplikacije i integracije za Claude na postojećim Laravel backendima, polazeći od koda i validacije koje već imate. Pišite nam na [email protected].

Imate projekat na umu?

Hajde da popričamo kako Conimex IT može da vam pomogne da osmislite, izgradite i objavite svoj sledeći proizvod.

Kontaktirajte nas