הגדרת Model Context Protocol

במאמר הזה מוסבר איך להגדיר את API Gateway כך שיפעל כשרת Model Context Protocol‏ (MCP) מרוחק.

לפני שמתחילים

  • מוודאים שיש לכם מפרט OpenAPI 3.x תקין ל-API. אין תמיכה ב-MCP ב-OpenAPI 2.0.
  • חשוב לוודא שאתם מבינים את היסודות של API Gateway.

אימות ההגדרות

כשמעלים את מפרט OpenAPI, ‏ API Gateway מבצע את האימותים הבאים לגבי הגדרת ה-MCP:

  • מיקום: אפשר לציין את התוסף x-google-mcp-tool רק ברמת הפעולה הספציפית.
  • שיטת HTTP: אפשר לחשוף רק פעולות GET,‏ POST,‏ PUT,‏ PATCH ו-DELETE ככלי MCP.
  • שם הכלי: השם של הכלי צריך להיות זהה ל-[A-Za-z0-9_.-]{1,128} וייחודי במפרט.
  • תיאור: לכל כלי צריך להיות תיאור לא ריק (שנלקח מהתיאור, הסיכום או ההחלפה של הפעולה). פעולות ללא תיאור שניתן לפתור נדחות.
  • אבטחה: אם מגדירים אימות ל-tools/list, צריך לציין בדיוק סכימת אבטחה אחת של JWT שמוגדרת בקטע components.securitySchemes. ב-Public Preview אין תמיכה באבטחת מפתחות API עבור tools/list.

מודל אימות

‫API Gateway מחיל כללי אימות שונים בהתאם לשיטת ה-MCP שנקראת:

  • מחזור החיים של הפרוטוקול: השיטות initialize ו-notifications/initialized הן לא מאומתות.
  • הפעלת כלי (tools/call): נעשה שימוש חוזר במדיניות האימות שהוגדרה עבור הפעולה הבסיסית במפרט OpenAPI. הוא אוכף את אותם דרישות של מפתח API או JWT כמו קריאה ישירה לנקודת הקצה של REST.
  • גילוי כלי (tools/list): כברירת מחדל, השיטה הזו לא מאומתת. עם זאת, כשיטה מומלצת לאבטחה, מומלץ מאוד להגן על גילוי כלי על ידי הפעלת אימות לשיטה הזו באמצעות tools-list.security. אם בוחרים להפעיל אימות, צריך להשתמש בסכמת אבטחה של JWT. אימות באמצעות מפתח API לא נתמך ב-tools/list.

שלבים להגדרת MCP

כדי לחשוף את ה-API ככלי MCP:

1. זיהוי הפעולות שרוצים לחשוף

בודקים את מפרט OpenAPI ומחליטים אילו פעולות צריכות להיות זמינות לסוכני AI.

2. עדכון מפרט OpenAPI

אפשר להפעיל את ה-MCP באופן גלובלי לכל הפעולות שעומדות בדרישות, או להגדיר אותו לכל פעולה בנפרד.

הפעלה גלובלית

כדי להפעיל את MCP באופן גלובלי, מוסיפים את השדה mcp אל x-google-api-management ברמת המסמך:

openapi: 3.0.3
info:
  title: Bookstore API
  version: 1.0.0
x-google-api-management:
  mcp: true
  backends:
    bookstore-backend:
      address: https://bookstore-backend-12345678.us-central1.run.app

כשמפעילים את התכונה באופן גלובלי, כל הפעולות שעומדות בדרישות (על סמך שיטת ה-HTTP והנתיב) מוצגות ככלים של MCP. כברירת מחדל, שם הכלי הוא operationId הפעולה, והתיאור הוא התיאור או הסיכום של הפעולה.

הגדרות לכל פעולה

אפשר לבטל את ההגדרות הגלובליות או לחשוף פעולות באופן סלקטיבי באמצעות x-google-mcp-tool:

paths:
  /v1/shelves/{shelf}:
    delete:
      operationId: deleteShelf
      summary: Delete a shelf.
      x-google-backend: bookstore-backend
      x-google-mcp-tool:
        name: delete_shelf
        description: "Permanently delete a shelf and every book on it."

אפשר גם להשבית פעולה שהופעלה באופן גלובלי על ידי הגדרת x-google-mcp-tool: false.

כברירת מחדל, השיטה tools/list (שמפרטת את הכלים הזמינים) לא מאומתת. כשיטה מומלצת לאבטחה, מומלץ מאוד לאכוף אימות על ידי הגדרת tools-list.security בקטע x-google-api-management/mcp. חובה להשתמש בסכימת JWT. אין תמיכה במפתחות API בשיטה הזו.

x-google-api-management:
  mcp:
    tools-list:
      security:
        myJWT: []
כדי להחריג את הפעולות האלה באופן מפורש.

4. יצירה ופריסה של הגדרת ה-API

יוצרים הגדרת API מהמפרט עם ההערות ומפריסים אותה לשער באמצעות התהליך הרגיל. פרטים נוספים מופיעים במאמר בנושא פריסת API בשער.

5. אימות התמיכה ב-MCP

אחרי הפריסה, אפשר לוודא שהשער משרת בקשות MCP.

לחיצת יד

שולחים בקשת אתחול כדי לקבוע את גרסת הפרוטוקול והיכולות:

curl -X POST https://my-gateway-12345.uc.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-11-25",
    "capabilities": {},
    "clientInfo": {"name": "demo-client", "version": "1.0.0"}
  }
}'

אישור לחיצת היד

מאשרים את האתחול. השער מגיב עם HTTP 202 Accepted:

curl -X POST https://my-gateway-12345.uc.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc": "2.0", "method": "notifications/initialized"}'

לכל הכלים

מציגים את רשימת הכלים הזמינים:

curl -X POST https://my-gateway-12345.uc.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}'

איך הארגומנטים ממופים לבקשת REST

הארגומנטים שמועברים לכלי ממופים לבקשת ה-REST הבסיסית על סמך מפרט OpenAPI:

  • פרמטרים של נתיב ושאילתה: הופכים למאפיינים ברמה העליונה באובייקט arguments, עם מפתח לפי שמות הפרמטרים שלהם ב-OpenAPI.
  • גוף הבקשה: מוצב בתוך נכס יחיד בשם body. לדוגמה, כדי ליצור משאב, מעבירים את {"body": {"fieldName": "value"}}.
  • כותרות: הופכות גם הן לנכסים ברמה העליונה. השער מחדיר אותן ככותרות HTTP רגילות בקריאה אל השרת העורפי.

אי אפשר להבחין בין בקשת הקצה העורפי שעברה המרה לבין בקשת REST ישירה לשירות הקצה העורפי. שירותי קצה עורפי לא יכולים להבדיל באופן פרוגרמטי בין קריאת REST ישירה לבין קריאה שבוצעה לאחר קידוד מחדש מ-MCP.

הפעלת כלי

להפעיל כלי ספציפי. אם פעולת ה-REST הבסיסית דורשת אסימוני אימות, צריך לוודא שאתם כוללים אותם:

curl -X POST https://my-gateway-12345.uc.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "delete_shelf",
    "arguments": {"shelf": "sci-fi"}
  }
}'

ניראות (observability)

בקשות MCP מניבות מדדים ויומנים רגילים של API Gateway. כדי להבחין בין תנועה של MCP לבין תנועה רגילה של REST, אפשר לבדוק את נתיב הבקשה (בדרך כלל מסתיים ב-/mcp) או להגדיר מדדים מותאמים אישית.

פתרון בעיות שקשורות לכשלים ב-MCP

פרוטוקול MCP מבחין בין כשלים בהעברה לבין כשלים בפרוטוקול. השער מחזיר HTTP 200 עם אובייקט שגיאה של JSON-RPC לשגיאות בפרוטוקול ובאפליקציה, כי תגובות שאינן 200 עלולות לגרום ללקוחות רבים של MCP להיכשל בשכבת התעבורה.

בטבלה הבאה מתוארים תסמינים נפוצים ופתרונות:

תיאור הבעיה קוד JSON-RPC סטטוס HTTP משמעות ותיקון אופייני
השיטה אסורה לא רלוונטי 405 בקשה שאינה POST הגיעה אל /mcp. יש תמיכה רק ב-HTTP POST.
שגיאה בניתוח JSON -32700 400 תוכן הבקשה הוא לא JSON תקין.
חסר/לא תקין Method או ID -32600 200 התוכן הוא JSON תקין אבל לא בקשת JSON-RPC תקינה. צריך לוודא שמילאתם את שדות החובה (jsonrpc, ‏ method, ‏ id).
השיטה לא נתמכת -32601 200 השיטה לא נכללת בהיקף הנתמך (לדוגמה, ping).
גרסת פרוטוקול לא נתמכת -32602 200 השם protocolVersion מציין גרסה שהשער לא תומך בה.
חסרה גרסת הפרוטוקול -32602 200 הפרמטרים של initialize לא כוללים את protocolVersion או שהוא לא מחרוזת.
כלי לא ידוע -32602 200 שם הכלי לא נמצא. מנקים את מטמון הלקוח או מאמתים את הפריסה.
ארגומנטים לא תקינים של כלי -32602 200 הארגומנטים חסרים או לא תקינים. בודקים את הקינון של המפתח body.
הגוף גדול מדי -32000 200 מטען הייעודי (payload) של התגובה חרג ממגבלות הגודל.
הגוף של ההודעה גדול מדי לא רלוונטי 413 גודל הגוף של בקשת ה-HTTP הגולמית חרג ממגבלות התעבורה של השער.
שגיאה בחיבור לשרת -32000 200 תגובת ה-Backend לא ניתנת לניתוח. בודקים את היומנים.
אין הרשאה / אסור לא רלוונטי 401 / 403 האימות נכשל. התשובה מכילה כותרת WWW-Authenticate שמפנה למטא-נתונים של משאב מוגן.

שגיאות באפליקציית ה-Backend בדרך כלל מופיעות כתגובת JSON-RPC מוצלחת (HTTP 200) עם result.isError: true שמכיל את גוף השגיאה ב-Backend.

המאמרים הבאים