הדף הזה רלוונטי ל-Apigee ול-Apigee Hybrid.
לצפייה במאמרי העזרה של
Apigee Edge.
בדף הזה מוסבר איך לפתור בעיות בפריסה של שרתי proxy לזיהוי MCP. אתם יכולים להשתמש בדף הזה כדי להבין את מחזור החיים של הקצאת משאבים אסינכרונית בפריסות של MCP, לפתור קודי שגיאה ולאמת את הקישוריות בזמן הריצה.
הסבר על פריסת MCP
פריסת שרת ה-proxy של MCP Discovery היא תהליך אסינכרוני עם כמה שלבים, שמוודא שההגדרות מופצות באופן מלא בתשתית של Apigee ו- Google Cloud לפני שהפריסה של שרת ה-proxy מסתיימת.
בזמן ששלבי ההקצאה האלה מתרחשים, בממשק המשתמש מוצג הסטטוס בהקצאה. בסיום התהליך, הסטטוס משתנה לנפרס. הסטטוס הזה מאשר שכל הרכיבים במורד הזרם הוקצו במלואם, ושהשרת proxy מוכן לטפל בתנועה.
פתרון בעיות
בקטעים הבאים מתוארות שגיאות ובעיות מוכרות שאתם עשויים להיתקל בהן במהלך השימוש ב-MCP ב-Apigee.
ה-backend לא מקבל ארגומנט של כלי במיקום הצפוי
הבעיה: קצה עורפי קורא ארגומנט של כלי ממיקום אחד של בקשה – מחרוזת השאילתה, כותרת או קובץ Cookie – אבל במפרט OpenAPI מוצהר שהפרמטר in נמצא במיקום אחר, ולכן הארגומנט מגיע למקום אחר בבקשה לקצה העורפי. הקריאה נכשלת או מתנהגת כאילו הארגומנט לא קיים.
תסמינים: הבקשה של tools/call מצליחה בשכבת ה-MCP והלקוח של ה-MCP מספק את הארגומנט, אבל ה-backend מגיב כאילו הערך חסר – למשל 400 לערך נדרש, או שמוחל ערך ברירת מחדל במקום הערך שנשלח.
הסיבה: הפרמטר מוגדר כ-in: header או כ-in: cookie במפרט של OpenAPI, ולכן Apigee שולחת את הערך שלו כ-request header או בכותרת Cookie במקום במחרוזת השאילתה. אם יש לכם קצה עורפי שקורא את הערך רק ממחרוזת השאילתה, הוא לא יראה אותו. מיקום הארגומנט של הכלי בבקשת הקצה העורפי
פתרון: מחליטים לאן הערך שייך ומוודאים שיש התאמה בין המפרט לבין הקצה העורפי:
- כדי לשמור את הערך במחרוזת השאילתה, צריך להצהיר על הפרמטר
in: query. - כדי לשלוח אותו ככותרת או כקובץ Cookie, משאירים את ההצהרה כמו שהיא וקוראים את הערך מהמיקום הזה בקצה העורפי.
ה-backend מפסיק לקבל קובץ Cookie שנשלח בבקשה של לקוח ה-MCP
הבעיה: קובץ Cookie שמגיע בבקשת ה-HTTP של לקוח ה-MCP (לדוגמה, קובץ Cookie זמני מלקוח מבוסס-דפדפן) מפסיק להגיע לקצה העורפי בחלק מהקריאות לכלי.
תסמינים: ה-backend מתנהג כאילו מבצע הקריאה החוזרת לא אומת או לא נמצא בסשן, וההתנהגות לא עקבית: אותה פעולה עובדת בחלק מהקריאות החוזרות ולא באחרות.
הסיבה: הפעולה מצהירה על פרמטר אחד או יותר מסוג in: cookie, והקריאות המושפעות סיפקו לפחות אחד מהם. הכותרת Cookie נכתבת מחדש במלואה במקום להוסיף לה, כך שבקריאות האלה היא נושאת רק את הפרמטרים המוצהרים של קובצי ה-Cookie, וכל קובץ Cookie אחר נמחק. בקשות שלא סיפקו אף אחד מהפרמטרים של קובצי ה-Cookie מעבירות את הכותרת ללא שינוי, ולכן רק חלק מהבקשות נכשלות. קובצי Cookie בבקשה לקצה העורפי
פתרון: מגדירים כל קובץ Cookie שה-backend צריך כפרמטר in: cookie בכל פעולה שצריכה אותו, כדי שהערך שלו תמיד יסופק על ידי הקריאה לכלי ולא יועבר בירושה מהבקשה של הלקוח. אין הגדרה ששומרת קובץ Cookie שלא הוצהר.
קודי סטטוס של תגובות שגיאה לקריאות לכלי ולמטא-נתונים
נקודות הקצה של Apigee MCP מחזירות קודי סטטוס של HTTP בהתאם למפרט של Model Context Protocol (MCP) ולתקני OAuth קשורים. הבנת ההתנהגות הזו עוזרת לכם לטפל נכון בשגיאות בלקוח ה-MCP או בסוכן ה-AI.
בטבלה הבאה מפורטים קודי הסטטוס שמוחזרים על ידי נקודות הקצה של Apigee MCP:
| תרחיש | קוד מצב HTTP | גוף התשובה |
|---|---|---|
הפעלת הכלי נכשלת ב-tools/call (לדוגמה, ה-API של הקצה העורפי מחזיר שגיאה מסוג 4xx או 5xx, כמו שגיאת אימות או שדה חובה חסר). |
200 OK |
CallToolResult עם result.isError שמוגדר ל-true ופרטי השגיאה ב-content. כך לקוח ה-MCP וסוכן ה-LLM יכולים לקרוא את השגיאה ולתקן אותה (לדוגמה, על ידי בקשה חוזרת של הקלט החסר וניסיון חוזר) במקום לסיים את הסשן. |
המטא-נתונים של המשאב המוגן (PRM) של OAuth לא מוגדרים או שלא ניתן למצוא אותם בכתובת /.well-known/oauth-protected-resource/mcp. |
404 Not Found |
מציין שאין מטא-נתונים של משאבים מוגנים במיקום המבוקש. |
| טוקן הגישה חסר, לא תקין או שפג תוקפו. | 401 Unauthorized |
כולל אתגר WWW-Authenticate כדי להפעיל את תהליך הגילוי של OAuth. |
| היקף ההרשאות של טוקן הגישה לא מספיק. | 403 Forbidden |
כולל אתגר WWW-Authenticate כדי להפעיל את תהליך האימות
המתקדם. |
דוגמה: גוף התגובה לשגיאה בהפעלת הכלי
אם קריאה לכלי נכשלת, Apigee MCP מחזיר את הערך HTTP 200 OK ומדווח על הכישלון באובייקט result של JSON-RPC, כאשר isError מוגדר ל-true. השגיאה המקורית שהוחזרה על ידי הקצה העורפי נשמרת: גוף התגובה של הקצה העורפי ממוקם מילה במילה (כמחרוזת) ב-result.content[].text. לדוגמה, אם ה-backend מחזיר את הערך HTTP 404 עם גוף ההודעה {"error":"User 42 not found"}, התגובה של ה-MCP היא:
{ "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "{\"error\":\"User 42 not found\"}" } ], "isError": true } }
הערך של id תואם לערך של id בבקשה של tools/call.
אם ה-backend לא מחזיר גוף תגובה, text מכיל סיכום שנוצר במקום זאת, כמו Operation failed (HTTP 500).
לקוח ה-MCP צריך לבדוק את result.isError (לא את קוד הסטטוס של ה-HTTP) כדי לזהות קריאה שנכשלה לכלי. אם קוד הלקוח מצפה באופן ספציפי לסטטוס HTTP 4xx או 5xx כדי לאותת על שגיאה בהפעלת הכלי, הוא לא מזהה את השגיאה, כי התגובה היא HTTP 200 OK. צריך לעדכן את הלקוחות האלה כדי לקרוא את result.isError ואת המערך content.
שגיאות ברמת הפרוטוקול (לדוגמה, בקשת JSON-RPC בפורמט שגוי) שונות משגיאות בהפעלת הכלי: הן ממשיכות להופיע באובייקט error של JSON-RPC (לדוגמה, {"jsonrpc": "2.0", "error": {"code": -32700, ...}}) במקום ב-result.isError.
המלצה: לקוחות MCP שתואמים לתקנים מטפלים בקודי הסטטוס האלה באמצעות הלוגיקה שמוגדרת כברירת מחדל, ולכן לא נדרשים שינויים. אם הוספתם בעבר פתרון עקיף בצד הלקוח כדי לטפל בקודי סטטוס לא סטנדרטיים – לדוגמה, ניתוח של גוף תגובה שאינו 2xx לשגיאות tools/call, או התייחסות לתגובה 500 מנקודת הקצה של ה-PRM כ "מטא-נתונים לא מוגדרים" – מומלץ להסיר את הפתרון העקיף הזה. אחרת, יכול להיות שהלקוח ימשיך להשתמש בלוגיקת טיפול מיושנת במקום לעבד את קודי הסטטוס המתוקנים כרגיל.
מדיניות CORS לשיחות MCP מבוססות-דפדפן
צריך מדיניות של שיתוף משאבים בין מקורות (CORS) כשמבצעים קריאות ל-Apigee MCP ישירות מדפדפן (לדוגמה, כשבכלי לבדיקת MCP משתמשים בהגדרה "ישיר" במקום "באמצעות שרת proxy"). כדי לאפשר קריאות מבוססות-דפדפן, התבנית של MCP Discovery Proxy כוללת כברירת מחדל את מדיניות ה-CORS של Apigee ב-Request PreFlow של נקודת הקצה של שרת ה-proxy בחבילת ה-proxy.
אם נתקלתם בבעיות שקשורות ל-CORS כשאתם מבצעים קריאות ישירות מדפדפן, יכול להיות שתצטרכו לשנות את הגדרות המדיניות של CORS ב-Request PreFlow של נקודת הקצה של שרת ה-Proxy בחבילת ה-Proxy של MCP Discovery.
שגיאה בניתוח JSON בזמן שליחת בקשה לנקודת קצה של MCP
יכול להיות שתקבלו הודעת שגיאה דומה לזו (או עם קוד שגיאה והודעה אחרים) כשתשלחו בקשה לנקודת הקצה של ה-MCP:
{
"error": {
"code": -32700,
"message": "JSON parse error"
},
"id": null,
"jsonrpc": "2.0"
}במקרה כזה, מומלץ לבדוק את הפרטים הבאים:
- הזנתם את כתובת ה-URL הנכונה של נקודת הקצה של ה-MCP.
- הבקשה בפורמט הנכון.
- אתם משתמשים בשיטה נתמכת.
- הפעלתם והגדרתם את שרת ה-proxy של MCP Discovery ב אזור נתמך. כאן מפורטים האזורים שבהם יכולות להיות מגבלות קיבולת.
כשלים בפריסה
אם הפריסה של שרת ה-proxy לגילוי MCP נכשלה והסטטוס Failed מופיע בממשק המשתמש, אפשר לבדוק את הודעת השגיאה כדי לקבל פרטים נוספים. הנה כמה דוגמאות לכשלים נפוצים:
- הגדרת הרשת נכשלה או סכימה לא נתמכת ב-OAS: השגיאות האלה בדרך כלל מצביעות על בעיה במפרט OpenAPI. מוודאים שהמפרט תקין ושהוא משתמש בגרסה נתמכת.
- מגבלות קיבולת באזור (Apigee בלבד): אם מופיעה שגיאה שקשורה לכישלון בהקצאת מאזן העומסים, או שסטטוס ההקצאה לא משתנה ל-Deployed, יכול להיות שהסיבה לכך היא מגבלות קיבולת זמניות בתשתית באחד מהאזורים הבאים:
asia-east2asia-northeast3asia-southeast2australia-southeast1europe-central2europe-west12europe-west9me-central2us-central2
כדי לפתור את השגיאה, נסו לפרוס את שרת ה-proxy בסביבה באזור אחר. מצב הכשל הזה לא רלוונטי ל-Apigee hybrid, שבו תשתית זמן הריצה היא האשכול שלכם.
- MCP לא מופעל באשכול (Apigee hybrid בלבד): אם פריסת שרת ה-proxy של MCP נשארת בסטטוס Provisioning ללא הגבלת זמן ולא מגיעה לסטטוס Deployed, צריך לוודא ש-MCP מופעל באשכול. אפשר לעיין בקטע אבחון בצד האשכול שבהמשך.
אבחון בצד האשכול (Apigee Hybrid בלבד)
מכיוון שמישור הנתונים של Apigee hybrid MCP פועל בתוך אשכול Kubernetes שלכם, מצבי כשל בתוך האשכול מאובחנים באמצעות kubectl מול האשכול.
כדאי לעבור על רשימת המשימות הבאה לאבחון לפי הסדר.
שלב 1: מוודאים ש-MCP מופעל באשכול
MCP נפרס כמשאב מותאם אישית של ApigeeDeployment (מנוהל על ידי מפעיל Apigee), ולא כ-Deployment רגיל של Kubernetes. בודקים את ה-MCP ApigeeDeployment:
kubectl -n APIGEE_NAMESPACE get apigeedeployment -l app=apigee-mcp-server
הפלט אמור להיראות כך (שמות המשאבים כוללים סיומת שנגזרת מהארגון, שמוצגת כאן בתור ORG_CR_SUFFIX):
NAME STATE NESTEDSTATE AGE apigee-mcp-server-default-ORG_CR_SUFFIX running 1h
אם הפקודה מחזירה את הערך No resources found in APIGEE_NAMESPACE namespace., סימן ש-MCP לא מופעל. חוזרים אל הפעלת MCP ב-Apigee Hybrid ומוודאים ש-enableMcpServer: true מוגדר כמפתח ברמה העליונה ב-overrides.yaml, וששדרגתם את גרסת ה-Helm של apigee-operator לפני הגרסה של apigee-org. בשלב 3 ובשלב 4 של תהליך ההפעלה מפורטות פקודות helm הנכונות.
שלב 2: מוודאים שה-pods של MCP פועלים
kubectl -n APIGEE_NAMESPACE get pods -l app=apigee-mcp-server
הפלט הצפוי (הסיומות של ה-pod יהיו שונות):
NAME READY STATUS RESTARTS AGE apigee-mcp-server-default-ORG_CR_SUFFIX-1170-abcd1234 2/2 Running 0 1h apigee-mcp-server-default-ORG_CR_SUFFIX-1170-efgh5678 2/2 Running 0 1h
שמות ה-Pod מבוססים על התבנית apigee-mcp-server-default-ORG_CR_SUFFIX-REV-POD_HASH, כאשר REV הוא גרסת התיקון של הגרסה ההיברידית בת ארבע הספרות (לדוגמה, 1170 לגרסה ההיברידית 1.17.0) ו-POD_HASH הוא סיומת אלפאנומרית בת שמונה תווים ששונה בכל Pod.
כל pod צריך להציג את הערך 2/2 בעמודה READY ואת הערך Running בעמודה STATUS. אם הפודים לא במצב Running,
הסיבה מופיעה
ב-kubectl -n APIGEE_NAMESPACE describe pod POD_NAME. הסיבות הנפוצות הן כשלים בשליפת תמונות (צריך לאמת את תעבורת הנתונים היוצאת (egress) מהאשכול אל מאגר התמונות שהוגדר ב-overrides.yaml) ואין מספיק מקום פנוי במעבד (CPU) או בזיכרון (צריך להגדיל את mcpServer.resources.requests ב-overrides.yaml).
שלב 3: בודקים את סטטוס המשיכה של הגדרת ה-sidecar
הקונטיינר המשני (sidecar) של apigee-mcp-server-config בכל pod של MCP שולף מדי פעם את הגדרות ה-MCP ממישור הבקרה של Apigee. בכל שליפה, המערכת מאחזרת את ההפניה להגדרה הנוכחית מ-apigee.googleapis.com, ואז מאחזרת את חבילת ההגדרות שאליה מפנים מ-Cloud Storage. מישור הנתונים של MCP מתחיל להציג תנועה של כלי MCP ב-https://mcp.apigee.internal/mcp אחרי שפעולת המשיכה מסתיימת בהצלחה עם הגדרה תקינה.
לפני השליפה הראשונה המוצלחת עם הגדרה תקינה (כי עדיין לא נפרס שרת proxy לגילוי MCP בארגון, או כי ה-sidecar לא יכול להגיע למישור הבקרה), הפודים של MCP נשארים במצב Ready אבל הבקשות ל-https://mcp.apigee.internal/mcp נכשלות עם השגיאה connection refused.
בודקים את היומנים של ה-sidecar כדי לראות איזה מקרה רלוונטי:
kubectl -n APIGEE_NAMESPACE logs -l app=apigee-mcp-server -c apigee-mcp-server-config --tail=100
- שורה חוזרת של
infoשמציינת שאין הגדרת MCP ממישור הבקרה: מישור הבקרה של Apigee החזיר תגובה מוצלחת, אבל עדיין לא נפרס פרוקסי של MCP Discovery בארגון. זהו המצב היציב הצפוי במהלך תהליך ההצטרפות. כדי להעביר את מישור הנתונים של MCP למצב הצגה, צריך לפרוס שרת פרוקסי לזיהוי MCP בהתאם למדריך למתחילים בנושא MCP.{"level":"info","ts":1787582542.68,"caller":"mcpsidecar/sidecar.go:397","msg":"mcpsidecar: no MCP config from CP yet; skipping tick, pod stays Ready via seed","org":"YOUR_ORG","mcp_server_id":"default"} errorשורה עם מונהconsecutive_failures: היומנים של Sidecar הם קובצי JSON מובְנים. אם מופיע הערך{"level":"error","ts":1787613247.74,"caller":"mcpsidecar/sidecar.go:...","msg":"mcpsidecar: ...","org":"YOUR_ORG","mcp_server_id":"default","consecutive_failures":185,"error":"<wrapped error text>"}"level":"error"עם מונהconsecutive_failuresשעולה, סימן שה-sidecar לא הצליח להשלים את משיכת ההגדרות. ה-sidecar מנסה שוב באופן אוטומטי עם השהיה לפני ניסיון חוזר (backoff), ומאפס את המונה ל-0 בשליפה הבאה שמצליחה.סיבות נפוצות שכדאי לבדוק אם המונה הזה ממשיך לעלות:
- חשבון השירות
apigee-watcherב-Google Cloud לא נמצא ברשימהwatcher_identitiesבמשאבcontrolPlaneAccessשל הארגון ב-Apigee. כדי להוסיף את ההרשאה ולוודא שהיא התקבלה, עיינו בקטע שלב 2: מתן גישה לזהות של הצופה להגדרות של MCP במישור הבקרה בתהליך ההפעלה. - תעבורת הנתונים היוצאת מהאשכול אל
apigee.googleapis.comאו אלstorage.googleapis.comחסומה. שתי נקודות הקצה חייבות להיות נגישות מהפודים של MCP (ראו דרישות הרשת לתעבורת נתונים יוצאת בתהליך ההפעלה). - חשבון השירות
apigee-watcherלא יכול לקבל טוקני גישה ל-Google Cloud מהאשכול הזה. אם רכיבים קיימים של Apigee Hybrid באותו מרחב שמות מדווחים גם על כשלים באימות, קודם צריך לטפל בבעיית האימות המשותפת. - שגיאה זמנית במישור הבקרה של Apigee או ב-Cloud Storage. אם המונה ממשיך לעלות במשך תקופה ארוכה אחרי ששללתם את הסיבות שלמעלה, פנו לתמיכה של Apigee.
- חשבון השירות
שלב 4: מוודאים שהוזרקו hostAliases של מעבד הבקשות
כשמפעילים את MCP, מפעיל Apigee מוסיף רשומת hostAliases אחת למפרט ה-pod של מעבד הבקשות (MP). הרשומה מכילה כתובת IP אחת (ClusterIP של שירות MCP) ושני שמות מארחים: mcp.apigee.internal ו-ORG_NAME.mcp.apigee.internal באותיות קטנות. מוודאים שההזרקה הצליחה:
kubectl -n APIGEE_NAMESPACE get pods -l app=apigee-runtime \ -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.hostAliases}{"\n"}{end}'
לכל pod של MP שמופיע ברשימה חייבת להיות רשומה של hostAliases שמכילה גם את mcp.apigee.internal וגם את ORG_NAME.mcp.apigee.internal באותיות קטנות, שמצביעה על ה-ClusterIP של שירות ה-MCP. כל פוד של MP שמוצגת בו רשומה ריקה או חסרה נוצר לפני שהופעל MCP. מוחקים את ה-Pod המושפע של ה-MP כדי שהבקר של ApigeeDeployment ייצור אותו מחדש מהמפרט הנוכחי של ה-Pod (שכולל את הרשומה hostAliases שהוזרקה):
kubectl -n APIGEE_NAMESPACE delete pod -l app=apigee-runtime
שלב 5: אימות מקצה לקצה
כדי לבצע בדיקה מקצה לקצה ששולחת בקשת initialize בפועל דרך מישור הנתונים של MCP, צריך לפרוס שרת proxy לזיהוי MCP ולפעול לפי המדריך למתחילים בנושא MCP.
לפני שפורסים את שרת ה-proxy של MCP Discovery בארגון, בקשות אל https://mcp.apigee.internal/mcp נכשלות עם השגיאה connection refused, גם אם מעבד הבקשות יכול להגיע לפודים של MCP (ראו שלב 3).
בקשות תמיכה
אם פתחתם בקשת תמיכה שקשורה למישור הנתונים של MCP ב-Apigee Hybrid, צרפו את הפלט הבא כדי לזרז את האבחון:
kubectl -n APIGEE_NAMESPACE logs -l app=apigee-mcp-server --all-containers --tail=1000kubectl -n APIGEE_NAMESPACE describe pod -l app=apigee-mcp-server-
kubectl -n APIGEE_NAMESPACE get pods -l app=apigee-mcp-server -o wideו-kubectl -n APIGEE_NAMESPACE get svc -l app=apigee-mcp-server. - פלט עדכני של
overrides.yamlו-helm history APIGEE_ORG_RELEASE_NAME -n APIGEE_NAMESPACE(כאשרAPIGEE_ORG_RELEASE_NAMEהוא שם הגרסה של Helm לתרשיםapigee-org; אפשר למצוא אותו באמצעותhelm list -n APIGEE_NAMESPACE | grep apigee-org). לפני שמשתפים אתoverrides.yaml, צריך לצנזר חומרים סודיים, כולל:- כל מפתח מוטבע של חשבון שירות ב-
gcp.workloadIdentity, ב-envs[].serviceAccountPathsאו ב-mcpServer.serviceAccountPath. - כל אישורי ה-TLS או המפתחות הפרטיים ב-
virtualhosts. - שדות הסיסמה של
cassandra.auth. - כל פרטי הכניסה המוטבעים שההגדרות האישיות שלכם מעבירות לאופרטור.
- כל מפתח מוטבע של חשבון שירות ב-
- הפקודה והתגובה המלאות של
curlשמשחזרות את הבעיה.
אי אפשר לשנות את סגנון ה-API ל-MCP ב-API Hub
אם משאב API עם פעולות API קיימות כבר נמצא ב-Apigee API hub, אי אפשר לשנות את המאפיין API style של המשאב הזה ל-MCP. כדי לרשום API ב-Apigee API hub כ-MCP API, צריך לבחור בסגנון MCP כשרושמים את ה-API בפעם הראשונה, או לוודא שאין פעולות במשאב ה-API לפני שמשנים את הסגנון ל-MCP.
אם נתקלתם בבעיות אחרות, עיינו במאמר שימוש בניפוי באגים כדי לקבל מידע מפורט על השימוש בכלי ניפוי הבאגים במסוף Google Cloud לניתוח בקשות ותגובות אל שרת ה-proxy של MCP Discovery וממנו.