Ugrás a tartalomhoz
← Vissza a naplóhoz

MCP UI actions — hogyan vezérli a chat a kosár menetét

Hat MCP tool a kosár-checkout flow-ban (remove/coupon/proceed/fill/consent/submit). Mindegyik preview-and-confirm. XSS-védelem: Zod schema + textContent rendering.

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:

  1. 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?".
  2. 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?".
  3. cart.proceedToCheckout — átvitel a checkout oldalra. Paraméter: nincs. Preview: "Átviszlek a megrendelési oldalra. Folytatjuk?".
  4. 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?".
  5. 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.
  6. 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:

  1. Schema-validáció — minden tool input Zod schema-n megy át. cart.applyCoupon.code például: z.string().min(1).max(64).regex(/^[A-Z0-9_-]+$/). A <script> egyszerûen nem áll össze.
  2. Preview render-pipeline — a panel a tool-paramétereket plain text node-ban rendereli (textContent, soha innerHTML). 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:

  1. Felhasználó: "Töröld a Starter-t, és tegyél hozzá kupont a kosárhoz."
  2. Chat: "Eltávolítom a Starter license tételt (1 db, 19€). Megerõsíted?"
  3. Felhasználó: ✅
  4. Chat: "Van egy aktív SUMMER25 kupon (–25%). Alkalmazzam?"
  5. Felhasználó: ✅
  6. Chat: "Kész. Az új végösszeg: 73.50€. Megrendelési oldalra megyünk?"
  7. Felhasználó: ✅ → cart.proceedToCheckout lefut.

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ó.

Beszéljünk a projektedről

Mondd el, mit építesz — meglátjuk, hogyan segíthetünk.