MCP UI actions — hogyan vezérli a chat a kosár menetét
A Nortinia AI Chat egyik legtöbb félreértést okozó képessége az UI vezérlés. "A chat klikkel helyettem?" — igen, de nem úgy ahogy gondolod. A chat nem egy láthatatlan kurzort mozgat. A chat tool-okat hív meg, amelyeket a frontend regisztrál a useRegisterUIActions hook-on át. Minden hívás preview-and-confirm.
A hat kosár-folyamati tool
A cart + checkout flow-ban hat MCP tool van regisztrálva per oldal-állapot:
cart.removeItem— egy tétel törlése a kosárból. Paraméter:lineId. Preview: "Eltávolítom a kosárból: Pro license (1 db, 49€). Megerõsíted?".cart.applyCoupon— kuponkód alkalmazása. Paraméter:code. Preview: "Alkalmazom a SUMMER25 kódot (–25% a kosár teljes árából). Megerõsíted?".cart.proceedToCheckout— átvitel a checkout oldalra. Paraméter: nincs. Preview: "Átviszlek a megrendelési oldalra. Folytatjuk?".checkout.fillField— egy mezõ kitöltése. Paraméter:fieldId,value. Preview: "Kitöltöm az email mezõt ezzel: anna@vasarlo.hu. Megerõsíted?".checkout.toggleConsent— checkbox bekapcsolása (ÁSZF, GDPR). Paraméter:consentId. Preview: "Bekapcsolom az ÁSZF-elfogadás jelölõnégyzetet. Megerõsíted?". A consent kifejezetten csak explicit user megerõsítés után aktiválható, nem implicitbõl.checkout.submitQuote— quote-only checkout esetén ajánlatkérés beküldése. Paraméter: nincs (a mezõket a felhasználó töltötte ki). Preview: "Beküldöm az ajánlatkérést. Megerõsíted?".
Minden tool a frontenden van regisztrálva. A chat backend csak hívja õket. A panel megjeleníti a preview-t, és csak a felhasználó kifejezett "igen" / OK kattintása után indul el az akció.
Az XSS osztály, amit auditáltunk
A tool-paraméterek visszacsatolódnak a UI-ba (preview-szövegben, dashboard-eseményekben). Ez egy klasszikus XSS-vektor: ha a modell <script>alert(1)</script> értéket ad, és a panel ezt naivan HTML-be teszi, megsérül a tenant biztonsága.
Két védelmi réteg fut:
- Schema-validáció — minden tool input Zod schema-n megy át.
cart.applyCoupon.codepéldául:z.string().min(1).max(64).regex(/^[A-Z0-9_-]+$/). A<script>egyszerûen nem áll össze. - Preview render-pipeline — a panel a tool-paramétereket plain text node-ban rendereli (
textContent, sohainnerHTML). Még ha valami áthúzná is a schema-szûrõt, a böngészõ nem értelmezi HTML-ként.
A pen-teszt két kerek (2026 január, március) zéró talált sebezhetõséget hozott a chat-tool felületen. Ez a két réteg megtartja.
A per-tenant tool registry
Nem minden tenant futtatja mind a hat tool-t. A cart.applyCoupon például egy ajánlatkérõs tenant-on (pl. nortinia.com /tanacsadas flow) értelmetlen — ott nincs kupon. A registry tenant-szinten korlátozható:
// per-tenant tool registry példa
useRegisterUIActions([
cartRemoveItem,
cartProceedToCheckout,
checkoutFillField,
checkoutToggleConsent,
checkoutSubmitQuote,
// cartApplyCoupon szándékosan kihagyva — quote-only kosár
]);
A backend a tenant-konfiguráció alapján határozza meg, hogy a model promptjába melyik tool-ok kerülnek bele. A modell nem tud olyan tool-t hívni, amit a frontend nem regisztrált — duplán védve a tenant logikájával.
Mit jelent ez gyakorlatban
Egy átlagos kosár-folyamati session így néz ki:
- Felhasználó: "Töröld a Starter-t, és tegyél hozzá kupont a kosárhoz."
- Chat: "Eltávolítom a Starter license tételt (1 db, 19€). Megerõsíted?"
- Felhasználó: ✅
- Chat: "Van egy aktív SUMMER25 kupon (–25%). Alkalmazzam?"
- Felhasználó: ✅
- Chat: "Kész. Az új végösszeg: 73.50€. Megrendelési oldalra megyünk?"
- Felhasználó: ✅ →
cart.proceedToCheckoutlefut.
Négy chat-üzenet, három kattintás, kosár-kasszás folyamat lefutott. Hagyományosan ez 6-8 navigáció + form-mezõ klikkelés.
Tanulság
Az MCP UI actions nem egy varázs. Egy fegyelmezett kontrakt a chat és a frontend között, amit kódba zártunk, schema-val védtünk, és tenant-szinten konfigurálható. A varázslat az, hogy ettõl egyszerûnek érzi a felhasználó.