לקוח השער של המרקט (external_mcp)

איך האתר מתחבר לשער ה-MCP של Wizzo Market, מושך כלי מוצרים (kama, poosh, radar ועוד), קורא להם ומחליט איזה כלי כותב. כולל חתימות מלאות ומלכודות.

⏱ 5 דק' קריאה 976 מילים ערוך דף זה ב-GitHub

הספרייה external_mcp היא הלקוח שדרכו ה-CMS מגיע לכלים של שירותי Wizzo Market שהאתר משלם עליהם: אנליטיקה, הפצה, חדשות ועוד. במקום חיבור נפרד לכל מוצר יש שער אחד, והספרייה מציגה את הכלים שלו כאילו היו כלים של האתר, כך ש-שרת ה-MCP, סוכני ה-AI ו-צ'אט האדמין משתמשים בהם בלי לדעת מאיפה הם באו.

איך זה עובד#

  1. האתר מתחבר לשער פעם אחת: connect_gateway() שולחת למרקט את כתובת ה-MCP של האתר (<env_url>/system/mcp) ואת טוקן אתר, ומקבלת טוקן לשער. המצב נשמר ב-PARAMS תחת mcp_gateway.
  2. remote_tools() שואלת את השער אילו כלים קיימים, ושומרת את התשובה במטמון ל-6 שעות (CACHE_HOURS).
  3. כל כלי מתפרסם בשם <product>_<tool>, למשל kama_sql_query. השער עצמו משתמש ב-<product>__<tool> (קו תחתון כפול), והספרייה מתרגמת בשני הכיוונים.
  4. call() מעבירה קריאה לשער ומחזירה ["ok" => true, "data" => ...] או ["ok" => false, "error" => ...].

חיבור לא דורש רכישה נפרדת של "mcp": האתר מקבל גישה לכלים של מוצרים שכבר משולמים לו. החיבור כן דורש מפתח API של המרקט (wizzo_market_api_key).

מידע

המוצרים wizzo ו-cms תמיד מוסרים מהרשימה כדי שלא יתנגשו בכלי האתר. גם seok מוסר, חוץ מכשמנוע ה-SEO המאוחסן פעיל (SeoHosted::enabled()), ואז הכלים seok_* הם כלי ה-SEO היחידים של האתר.

קבועים#

קבועערךמשמעות
GATEWAY_URL_DEFAULThttps://mcp.wizzo.market/mcpכתובת השער כשלא נשמרה כתובת אחרת
GATEWAY_PARAMmcp_gatewayשם הפרמטר שבו נשמר מצב החיבור
MARKET_CONNECT_URLhttps://market.wizzo.media/api/mcp?api_action=cms_connectנקודת ההתחברות במרקט
MARKET_AGENT_SERVERS_URLhttps://market.wizzo.media/api/agent_serversטוקנים ייעודיים לסוכנים
CACHE_KEY, CACHE_HOURSexternal_mcp_tools, 6מטמון רשימת הכלים
CONNECT_BACKOFF_HOURSכ-5 דקותהשהיה אחרי כשל חיבור, כדי לא לנסות בכל בקשה
CONNECT_TIMEOUT, TIMEOUT6 ו-40 שניותזמני קריאה
READONLY_SERVERS["kama"]מוצרים שנחשבים לקריאה בלבד כשאין annotation
EXCLUDED_PRODUCTS["seok"]מוצרים שלא מתפרסמים (ראו למעלה)
KNOWN_LABELSמפהשמות תצוגה בעברית ל-target, kama, poosh, radar, wizzoai

API ציבורי#

כל המתודות סטטיות. המתודות הפנימיות (gateway_token, gateway_cms_token, gateway_rpc ועוד) הן private ואינן חלק מהחוזה.

חתימהמחזירהערות
gateway_state()מערך או nullמצב החיבור השמור ב-PARAMS mcp_gateway
connect_gateway($rotate = false)["ok" => bool, ...]מתחברת לשער. $rotate = true מנפיקה טוקן חדש. נכשלת אם אין מפתח מרקט
vouch_token()מחרוזתטוקן האתר שנשלח למרקט כ-X-Cms-Token. ריק כשהאתר לא מחובר
servers()[name => ["name","url","token"]]שרת לכל מוצר מותקן. כולם מצביעים לאותו שער
server($name)שורת שרת או null
agent_servers()רשימהטוקנים ייעודיים לכל מוצר, מטמון של 5 דקות
rpc($server, $method, $params = null)תשובה מפוענחתקריאת JSON-RPC גולמית. ב-tools/call מוסיפה לשם את <product>__
remote_tools()[product => [tools]]רשימת הכלים, ממטמון
manifest()רשימת כלים בפורמט MCPשמות <product>_<tool>, עם annotations אם יש
by_server()[["server","tools"], ...]אותה רשימה מקובצת, בצורה שהצ'אט צורך
resolve($tool)[product, bare_name] או nullפותרת מול הרשימה, לא לפי פיצול בקו תחתון
is_external($tool)boolהאם השם שייך לשירות חיצוני
is_write($tool)boolהאם הכלי כותב
server_is_write($name)boolהאם אחד מכלי המוצר עלול לכתוב
product_label($name)מחרוזתתווית תצוגה: מהשער, אחר כך KNOWN_LABELS, אחר כך שם באותיות גדולות
call($tool, $args)["ok","data"] או ["ok"=>false,"error","extra"]הקריאה עצמה
flush()-מרוקנת את המטמון באתר, וגם POST <gateway>/flush
flush_gateway()-רק את צד השער

קריאה לכלי מהקוד#

if (!class_exists("external_mcp")) {
    require_once CONFIG::$core_path . "/libraries/external_mcp.php";
}

// אילו כלים חיצוניים יש לאתר הזה
foreach (external_mcp::by_server() as $srv) {
    echo $srv["server"] . ": " . count($srv["tools"]) . " tools\n";
}

$tool = "kama_sql_query";   // שם בפורמט <product>_<tool>
if (external_mcp::is_external($tool)) {
    $res = external_mcp::call($tool, [
        "sql"   => "SELECT referrer_subtype AS engine, SUM(total_visits) AS visits
                    FROM kama_page_referrals
                    WHERE app_id = {APP_ID} AND date_day >= '2026-09-01'
                    GROUP BY referrer_subtype ORDER BY visits DESC",
        "limit" => 50,
    ]);
    if ($res["ok"]) {
        $data = $res["data"];            // JSON מפוענח, או טקסט
    } else {
        error_log("external tool failed: " . $res["error"]);
    }
}
הערה

השמות והארגומנטים של כל כלי נקבעים על ידי המוצר ולא על ידי הליבה (בדוגמה, sql ו-limit של KAMA, כפי ש-SeoGeo קורא להם, ו-{APP_ID} מוחלף על ידי השירות). בדקו את inputSchema ב-external_mcp::manifest() לפני שאתם קוראים לכלי חדש.

איך מחליטים אם כלי כותב#

הכרעה חשובה כי היא קובעת אם הכלי עובר dry-run וכניסה לתור האישורים (כלי ה-MCP). הסדר:

  1. אם ל-tool יש annotation readOnlyHint, הכלי כותב אם הערך false.
  2. אחרת, אם יש destructiveHint אמיתי, הכלי כותב.
  3. בלי annotation: כותב, אלא אם המוצר ב-READONLY_SERVERS.

הגישה הזהירה היא בכוונה: טעות לכיוון "כותב" עולה הערת dry-run מיותרת, וטעות לכיוון "קורא" עלולה להפעיל קמפיין או שידור אמיתיים.

דלת המרקט: connector#

המרקט מחבר ומנהל אתרים דרך /system/connector. האימות הוא מפתח ה-API של המרקט של האתר (בכותרת Authorization או X-Wizzo-Key, או בגוף ב-_key, api_key או _token), מושווה עם WIZZO_KEY::matches. כל פעולה נתמכת גם כ-?do=<action>.

פעולהמה עושה
GET (גילוי)מחזיר connector, גרסת ליבה, פרטי האתר, רשימת שירותים ויכולות
statusמצב MCP, סוכנים וביצועים
mcp_connectקורא ל-connect_gateway, גוף אפשרי {rotate: true}. כשל מחזיר 502
agents_readyרושם את האתר ב-stream ומעביר סוכנים ישנים פעם אחת. דורש WizzoAI פעיל, אחרת 409
seo_readyהכנת מנוע ה-SEO
oleg_readyהכנת יועץ הביצועים (בריאות וביצועים)

מלכודות#

שימו לב
flush() פונה גם לשער במרקט. אם הוא לא זמין, הקריאה נכשלת בשקט, והרשימה אצל חיבורי ChatGPT או Claude עלולה להישאר ישנה עד שתפוג. אחרי פריסה שמשנה כלים, הפעילו delete_cache דרך הגשר או את external_mcp::flush() ובדקו ב-tools/list.

  • הטוקן לשער נשמר באתר ב-PARAMS. הוא מקנה גישה לכלי המוצרים של האתר, לכן אל תחשפו את mcp_gateway בלוגים או בצילומי מסך.
  • אחרי כשל חיבור הספרייה לא מנסה שוב כ-5 דקות, ובינתיים הרשימה ריקה. זו לא תקלה בכלים עצמם.
  • עדכון גרסה מרוקן את המטמון (external_mcp::flush() מתבצע בסוף העדכון).

ראו גם#

מצאתם טעות או חוסר? תקנו את הדף או פתחו Issue בריפו. התיעוד נכתב מתוך הקוד של ליבה 5.0.115.