קטלוג ההטבות של חבר ובהצדעה, דרך MCP

פורסם במקור כפוסט בלינקדאין, והורחב כאן.

בניתי שרת MCP ציבורי מעל קטלוגי ההטבות של חמישה מועדונים — בהצדעה, חבר, ישראכרט, max ו-Cal — 22,877 הטבות בקטלוג אחד, שאפשר לשאול עליו בעברית חופשית. בניתי אותו כי חלק מהקטלוגים האלה יושבים מאחורי מסע התחברות מפרך, ואחד מהם גם מאחורי OTP ב-SMS. הוא יצא מעניין כי זה המקרה הכי נקי שנתקלתי בו שבו MCP עדיין מצדיק את עצמו.

הבעיה היא לא ההטבות, היא החיכוך

לא ברור לי למה די הרבה מועדוני צרכנות שמים את קטלוג ההטבות שלהם מאחורי אוטנטיקציה. זה באמת מונע ממשתמשים לנצל הטבות שהם כבר משלמים עליהן — לא כי ההטבה לא שווה, אלא כי הם לא יודעים שהיא קיימת, והדרך לגלות אותה ארוכה מדי.

הרבה כבר ניסו לפתור את זה. ההערכה שלי היא שהם נסגרו משילוב של חוסר עניין ציבורי וחוסר רצון של חברות האשראי לשתף פעולה. יש את אפליקציית FID, אבל בעיניי גם היא לא אינטואיטיבית מספיק לחיפוש, ובעיקר — היא דורשת להוריד אפליקציה לטלפון. למה לא web?

מתי MCP עדיין הגיוני

MCP נכנס לחיינו כרוח סערה, ואז יצא מהאופנה אחרי שכלי החיפוש החופשי המובנים השתפרו. אם המודל יכול פשוט לגלוש לאתר ולקרוא — למה להתקין שרת?

שלושה תנאים, ולדעתי צריך לפחות אחד מהם כדי להצדיק את העבודה:

  1. המידע נמצא מאחורי חומות. אף כלי חיפוש לא יראה קטלוג שדורש התחברות.
  2. הוא מבולגן ודורש ידע כדי לקרוא אותו. "20% הנחה" זה לא אותו דבר כשמדובר בזיכוי לכרטיס נטען, בהנחה במעמד החיוב או בהנחה בקופה.
  3. יש יותר מדי ממנו. 22,877 שורות לא נכנסות לקונטקסט של מודל, ולא צריך שייכנסו.

המקרה הזה מסמן את שלושתם. סעיף 3 הוא אובר-קיל כאן, אבל הוא מה שגורם לזה לעבוד: המידע מסונן דטרמיניסטית לפני שהוא מגיע למודל, והתנאים המלאים נשלפים רק להטבות שכבר נמצאו רלוונטיות.

דיאגרמת זרימה: חמישה מועדוני הטבות שכל אחד מהם נעול מאחורי התחברות, איסוף מדפדפן מחובר, נרמול ודה-דופליקציה ל-22,877 הטבות, אינדוקס סמנטי ל-22,877 וקטורים, בחירת מקורות על ידי המשתמש, חיפוש של קלוד, ותשובה עם ציטוט התנאים.
המסלול מהקטלוג הנעול ועד לתשובה. השלב הצהוב באמצע — בחירת המקורות — מצמצם את החיפוש עוד לפני שהוא מתחיל. בדיאגרמה פישטתי: בישראכרט, ב-max וב-Cal הקטלוג הציבורי לא דורש התחברות, רק דפדפן אמיתי.

מה יש בפנים

חמישה ארגונים, תשע קבוצות מקור. הקבוצות נפרדות כי הן באמת מתנהגות אחרת: הכרטיס הכחול של חבר הוא רשת בתי עסק, הארנק הדיגיטלי של בהצדעה הוא תקציב טעינה חודשי, ושובר הוא מוצר שקונים מראש.

מועדון קבוצות הטבות
בהצדעה שוברים, ארנק דיגיטלי 16,566
חבר כרטיס שחור, צהוב, כחול, שוברים 4,101
Cal חנות החוויות 1,208
max הטבות max 682
ישראכרט הטבות ישראכרט 320

הכול נשמר ב-SQLite אחד עם אינדקס FTS5 מעל שם, קטגוריה ועיר. קטלוג ציבורי בלבד — יתרות, טעינות חודשיות וארבע ספרות אחרונות של כרטיס לא נשמרות בכלל, ויש בדיקת יחידה שמקבעת את זה.

האיסוף היה החלק המלוכלך

אף מקור לא נאסף ב-curl. כולם חוסמים בקשות שלא מגיעות מדפדפן אמיתי, ושניים מהם — בהצדעה וחבר — דרשו גם דפדפן מחובר. כל אחד היה שונה:

  • בהצדעה — API פנימי שדוחה בקשות בלי כותרת OrganizationId (ה-SPA שולח גם native). אין bearer token; האימות הוא עוגיות HttpOnly, וההתחברות היא תעודת זהות ואז OTP ב-SMS. הקטלוג הוא עץ שצריך לטייל בו, והשרת מגביל קצב — אחרי בערך 1,500 צמתים ההשהיה מזנקת מכ-0.6 שניות לכ-3 שניות לבקשה, אז סריקה מלאה חייבת להיות אינקרמנטלית.
  • חבר — הכרטיס הכחול הוא קובץ JSON אחד למשתמש מחובר. הכרטיס הצהוב פשוט חושף את כל המערך ב-window.data. רשת האשראי, לעומת זאת, היא ממשק WebForms בלי דאטהסט מרוכז, ושם צריך לעבור עמוד-עמוד.
  • ישראכרט — קטלוג "ההטבות לכולם" כולו מוטמע כ-JSON בתוך ה-HTML של דף הבית. פנייה אחת מדפדפן היא כל האיסוף. אין צורך בהתחברות, אבל Cloudflare חוסם כל בקשה שלא מגיעה מדפדפן.
  • max — API פנימי מעל אפליקציית Angular. הפרמטרים club ו-region מקבלים את המחרוזת המילולית undefined; אם משמיטים אותם השרת מחזיר מערך ריק בלי שום שגיאה. זה עלה לי סבב שלם.
  • Cal — מאחורי מנגנון אנטי-בוט. אריחי הרשימה הם תמונות רקע בלי טקסט, אז את השמות והמחירים היה צריך לשלוף מדפי המוצר עצמם.

זה החלק שלא נראה בדמו, והוא רוב העבודה.

החלק הדטרמיניסטי

כל אחת מ-22,877 השורות מקודדת ל-embedding עם Titan v2 ב-512 מימדים. התוצאה היא מערך numpy יחיד בגודל 22,877 על 512 שיושב על הדיסק. חיפוש סמנטי הוא כפל מטריצות אחד ומיון — ברוט-פורס מיידי בסדר הגודל הזה, בלי שום vector DB.

מה שחשוב הוא מה לא קורה: הקטלוג לא נכנס לקונטקסט. חיפוש מחזיר לכל היותר 50 שורות רזות, והתנאים המלאים — האותיות הקטנות — נשלפים בקריאה נפרדת, לפי מזהה של הטבה ספציפית. המודל מקבל את האותיות הקטנות רק אחרי שכבר הוחלט שההטבה רלוונטית.

מה שהקטלוג הזה עוד לא יודע

תנאים ברמת ההטבה קיימים כרגע רק לחבר. נאספו 1,531 עמודים ב-28 ביוני 2026, אבל רק 758 מהם — רשת האשראי — מתחברים בפועל לשורות בקטלוג ומחזירים תנאים, ובכ-97% מהם מנגנון הזיכוי בכלל לא מופיע בעמוד, כי הוא כלל ברמת התוכנית ולא ברמת ההטבה הבודדת. לבהצדעה אין עדיין תנאים ברמת ההטבה, כי הם יושבים מאחורי אותו OTP.

יש גם חורים בקטלוג עצמו. ההנחות במעמד החיוב של max לא נתפסו — הנקודה הזו מחזירה אפס בלי התחברות. השדות של ישראכרט שנפתחים רק למשתמש מחובר ריקים. וב-Cal הקטגוריה שמותנית בזכאות ריקה גם היא. גם הרעננות לא אחידה: חלק מהקטלוג מיולי 2026 וחלק מיוני. מחיר או תנאי שמופיעים בתשובה הם נקודת פתיחה לבדיקה באתר הרשמי של המועדון, לא תחליף לה.

השרת עצמו

שישה כלים לקריאה בלבד: list_sources, search_promotions, list_categories, semantic_search, get_club_terms, get_offer_terms. התיאורים והסכמות מגיעים מאותה הגדרה שממנה מקבל אותם הסוכן שמאחורי הצ׳אט — מקור אמת אחד, ולא שני עותקים שמתפצלים עם הזמן.

הטרנספורט הוא streamable HTTP חסר-מצב עם תשובות JSON — בלי state בין קריאות, ותשובה שכל לקוח HTTP פשוט יודע לקרוא. אין אוטנטיקציה: זה קטלוג ציבורי וכלים לקריאה בלבד.

הכלי היחיד שכותב, report_issue, מוחרג פעמיים: גם מרשימת הכלים וגם בזמן הקריאה עצמה. זה לא כפל מיותר — ה-SDK מעביר לשרת גם שמות כלים שלא הופיעו ברשימה, ולכן הסינון ברשימה הוא נימוס והשומר בזמן הקריאה הוא החסם האמיתי. יש על זה טסט.

הכול רץ על מכונת EC2 אחת מסוג t4g.small ב-eu-central-1, בערך 14 דולר לחודש, עם nginx מול uvicorn וגישה ל-Bedrock דרך IAM role במקום מפתחות סטטיים. מגביל קיבולת של שמונה משימות במקביל דואג לכך שתנועת MCP לא תרעיב את הצ׳אט.

איך מתקינים

מ-Claude Code, שורה אחת:

claude mcp add --scope user --transport http yesh-et-ze https://yesh-et-ze.hopala.io/mcp

מהדפדפן: בהגדרות, Connectors → Add → Add custom connector, ואז מדביקים את אותו URL.

מסך ההגדרות של קלוד בלשונית Connectors, עם כפתור Add מסומן ותפריט נפתח שבו מסומנת האפשרות Add custom connector.
שלבים 1 ו-2: Connectors → Add → Add custom connector
חלון Add custom connector: שדה שם עם הערך yesh et ze, שדה כתובת עם https://yesh-et-ze.hopala.io/mcp מסומן, וכפתור Add מסומן.
שלבים 3 ו-4: מדביקים את כתובת ה-MCP ולוחצים Add. אין OAuth ואין מפתח.

יש גם צ׳אט, והוא סגור

מעל אותו קטלוג בניתי גם ממשק צ׳אט בעברית, עם בורר מקורות ומד שמראה את העלות המשוערת של השיחה הנוכחית בשקלים. הוא סגור כרגע מאחורי סיסמה; המשטח הציבורי הוא ה-MCP.

בורר המקורות בממשק הצ׳אט: כרטיסיות לבהצדעה, חבר, ישראכרט, max ו-Cal, כל אחת עם קבוצות המקור ומספר ההטבות שבהן, ומד שמציג עלות משוערת של 0.182 שקלים לשיחה.
בורר המקורות. כל תיבה שמסמנים מצמצמת את החיפוש לפני שהוא רץ.
תשובה בממשק הצ׳אט לשאלה על הנחות ושוברים לדומינוס פיצה, המפרטת הטבת ארנק דיגיטלי של בהצדעה עם 20 אחוז הנחה ותקרת טעינה חודשית, וטבלה של אזורים וערים לכרטיס הכחול של חבר.
שאלה אחת, שני מועדונים, כולל תקרת הטעינה החודשית ואיך בפועל מממשים.

מה אני לוקח מזה

MCP לא מת ולא ניצח. הוא כלי עם תנאי הצדקה ברורים: מידע מאחורי חומה, שדורש ידע כדי לקרוא אותו נכון, ושיש ממנו יותר מדי מכדי פשוט להדביק. רוב המידע בעולם לא עומד בשלושת התנאים. חלק לא קטן מהמידע שיושב בתוך ארגון דווקא כן.

אם יש לכם מערכת פנימית שאף אחד לא נכנס אליה כי המסע אליה ארוך מדי, ככה אני עובד — מתחילים במיפוי של מה באמת נעול ומה רק נראה ככה.

שאלות שחוזרות

איך רואים את כל ההטבות של חבר ובהצדעה במקום אחד?

בניתי שרת MCP ציבורי שמאחד את קטלוגי ההטבות של בהצדעה, חבר, ישראכרט, max ו-Cal — 22,877 הטבות בסך הכל. מחברים אותו לקלוד, בקוד או כ-custom connector בדפדפן, ושואלים בעברית חופשית. הנתונים הם קטלוג ציבורי בלבד; אין שם שום מידע אישי על הארנק או היתרה שלכם.

מתי בכלל שווה לבנות שרת MCP במקום להסתמך על חיפוש באינטרנט?

כשהמידע נמצא מאחורי אוטנטיקציה ולכן אף כלי חיפוש לא מגיע אליו, כשהוא מבולגן ודורש ידע כדי לקרוא אותו נכון, וכשיש יותר מדי ממנו מכדי להכניס אותו לקונטקסט של המודל. קטלוג הטבות של מועדון צרכנות מסמן את שלושת הסעיפים.

למה קטלוגי ההטבות של מועדוני הצרכנות סגורים מאחורי התחברות ו-OTP?

אין לי תשובה טובה, וזאת בדיוק הנקודה. החיכוך גורם לאנשים לא לממש הטבות שהם כבר משלמים עליהן, פשוט כי הם לא יודעים שהן קיימות. בפועל אף מקור לא נאסף ב-curl — כולם דורשים דפדפן אמיתי, ובהצדעה וחבר דורשים גם התחברות, בבהצדעה עם אימות ב-SMS.

כמה עולה להריץ שרת MCP ציבורי כזה?

בערך 14 דולר לחודש. הכול רץ על מכונת EC2 אחת מסוג t4g.small ב-eu-central-1, עם nginx ו-uvicorn, והגישה ל-Bedrock היא דרך IAM role של המכונה במקום מפתחות סטטיים.