排解 Apigee 中的 MCP 部署問題

本頁面適用於 Apigee 和 Apigee Hybrid。

查看 Apigee Edge 說明文件。

本頁面說明如何排解及解決 MCP 探索 Proxy 部署問題。您可以使用這個頁面,瞭解 MCP 部署作業的非同步佈建生命週期、解決錯誤代碼,以及驗證執行階段連線能力。

瞭解 MCP 部署作業

部署 MCP 探索 Proxy 是非同步的多步驟程序,可確保在 Proxy 部署完成前,設定已完整傳播至 Apigee 和 Google Cloud 基礎架構。

在這些下游佈建步驟進行期間,UI 會顯示 Proxy 處於「Provisioning」(佈建中) 狀態。程序完成後,狀態會變更為「已部署」。這個狀態表示所有下游元件都已完整佈建,且 Proxy 已準備好處理流量。

疑難排解

以下各節說明在 Apigee 中使用 MCP 時,可能會遇到的錯誤和已知問題。

問題:後端從一個要求位置 (查詢字串、標頭或 Cookie) 讀取工具引數,但 OpenAPI 規格宣告參數 in 位於不同位置,因此引數會抵達後端要求的其他位置。呼叫會失敗,或行為就像沒有引數一樣。

症狀:tools/call 要求在 MCP 層成功執行,且 MCP 用戶端提供引數,但後端回應時卻顯示值遺失,例如必要值出現 400,或套用預設值而非傳送的值。

原因:參數在 OpenAPI 規格中宣告為 in: header 或 in: cookie,因此 Apigee 會將其值做為要求標頭或在 Cookie 標頭中傳送,而不是在查詢字串中傳送。如果後端只從查詢字串讀取值,就不會看到該值。請參閱「後端要求中的工具引數位置」。

解決方法:決定值所屬的位置,並讓規格和後端保持一致:

  • 如要保留查詢字串中的值,請宣告 in: query 參數。
  • 如要以標頭或 Cookie 的形式傳送,請保留宣告,並從後端讀取該位置的值。

問題:MCP 用戶端發出的 HTTP 要求中包含 Cookie (例如瀏覽器用戶端的工作階段 Cookie),但某些工具呼叫無法將 Cookie 傳送至後端。

症狀:後端行為就像呼叫端未通過驗證或未在工作階段中,且行為不一致:相同作業在某些呼叫中有效,但在其他呼叫中無效。

原因:作業宣告一或多個 in: cookie 參數,且受影響的呼叫提供至少一個參數。Cookie 標頭會整體重寫,而非附加,因此在這些呼叫中,標頭只會包含宣告的 Cookie 參數,其他 Cookie 則會捨棄。未提供任何 Cookie 參數的呼叫會直接傳遞標頭,因此只有部分呼叫會失敗。請參閱「傳送至後端的要求中的 Cookie」。

解決方法:在需要後端 Cookie 的每項作業中,將這些 Cookie 宣告為 in: cookie 參數,這樣 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 代理就能讀取錯誤並復原 (例如重新提示輸入缺少的內容並重試),而不是終止工作階段。
未設定受 OAuth 保護的資源中繼資料 (PRM),或在 /.well-known/oauth-protected-resource/mcp 找不到。 404 Not Found 表示要求的位置沒有受保護的資源中繼資料。
缺少存取權杖,或權杖無效/已過期。 401 Unauthorized 包含 WWW-Authenticate 驗證,可驅動 OAuth 探索流程。
存取權杖範圍不足。 403 Forbidden 包含 WWW-Authenticate 驗證,可推動逐步授權流程。

範例:工具執行錯誤回應主體

工具呼叫失敗時,Apigee MCP 會傳回 HTTP 200 OK,並在 JSON-RPC result 物件中回報失敗,其中 isError 設為 true。後端傳回的原始錯誤會保留:後端回應主體會逐字 (以字串形式) 放入 result.content[].text。舉例來說,如果後端傳回 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 與 tools/call 要求的 id 相符。如果後端未傳回回應主體,text 會改為包含產生的摘要,例如 Operation failed (HTTP 500).

MCP 用戶端應檢查 result.isError (而非 HTTP 狀態碼),偵測工具呼叫是否失敗。如果用戶端程式碼特別預期 4xx 或 5xx HTTP 狀態來表示工具執行錯誤,則不會偵測到錯誤,因為回應是 HTTP 200 OK。請更新這類用戶端,以讀取 result.isError 和 content 陣列。

通訊協定層級錯誤 (例如格式錯誤的 JSON-RPC 要求) 與工具執行錯誤不同:這類錯誤會繼續在 JSON-RPC error 物件 (例如 {"jsonrpc": "2.0", "error": {"code": -32700, ...}}) 中傳回,而非在 result.isError 中傳回。

建議:符合標準的 MCP 用戶端會透過預設邏輯處理這些狀態碼,因此不需進行任何變更。如果您先前曾新增用戶端解決方法來處理非標準狀態碼,例如剖析非 2xx 回應主體來找出 tools/call 錯誤,或將 PRM 端點的 500 回應視為「未設定中繼資料」,建議您移除該解決方法。否則,用戶端可能會繼續使用過時的處理邏輯,而不是正常處理更正後的狀態碼。

瀏覽器 MCP 呼叫的 CORS 政策

直接從瀏覽器發出 Apigee MCP 呼叫時 (例如 MCP 檢查器使用「直接」設定,而非「透過 Proxy」),必須採用跨源資源共享 (CORS) 政策。MCP Discovery Proxy 範本預設會在 Proxy 繫結的 Proxy 端點要求 PreFlow 中,加入 Apigee CORS 政策,以便啟用瀏覽器呼叫。

如果直接從瀏覽器發出呼叫時遇到 CORS 相關問題,可能需要調整 MCP Discovery Proxy 繫結中 Proxy 端點要求 PreFlow 的 CORS 政策設定。

向 MCP 端點傳送要求時發生 JSON 剖析錯誤

向 MCP 端點傳送要求時,您可能會收到類似下列的錯誤訊息 (或不同的錯誤代碼和訊息):

{
  "error": {
    "code": -32700,
    "message": "JSON parse error"
  },
  "id": null,
  "jsonrpc": "2.0"
}

在這種情況下,建議您確認下列資訊:

  • 您已輸入正確的 MCP 端點網址。
  • 要求格式正確。
  • 您存取的是支援的方法。
  • 您已在 支援的地區啟用並設定 MCP Discovery Proxy。如需可能設有容量限制的區域清單,請參閱「部署失敗」。

部署失敗

如果 MCP Discovery Proxy 部署失敗,且使用者介面顯示「Failed」(失敗) 狀態,請查看錯誤訊息,瞭解詳細資訊。常見的失敗原因包括:

  • Networking configuration failed 或 Unsupported Schema in OAS:這些錯誤通常表示 OpenAPI 規格有問題。請確認規格有效,且使用支援的版本。
  • 區域容量限制 (僅限 Apigee):如果看到與負載平衡器佈建失敗相關的錯誤,或佈建狀態一直未變更為「已部署」,可能是下列其中一個區域暫時達到基礎架構容量限制:
    • asia-east2
    • asia-northeast3
    • asia-southeast2
    • australia-southeast1
    • europe-central2
    • europe-west12
    • europe-west9
    • me-central2
    • us-central2

    如要解決錯誤,請嘗試將 Proxy 部署至其他區域的環境。這項失敗模式不適用於 Apigee Hybrid,因為執行階段基礎架構是您自己的叢集。

  • 叢集未啟用 MCP (僅限 Apigee hybrid):如果 MCP Proxy 部署作業無限期停留在「佈建中」狀態,且從未達到「已部署」狀態,請確認叢集是否已啟用 MCP。請參閱下方的「叢集端診斷」。

叢集端診斷 (僅限 Apigee hybrid)

由於 Apigee hybrid MCP 資料層是在您自己的 Kubernetes 叢集內執行,因此叢集內故障模式會透過對叢集執行 kubectl 進行診斷。請依序完成下列診斷檢查清單。

步驟 1:確認叢集已啟用 MCP

MCP 會部署為 ApigeeDeployment 自訂資源 (由 Apigee 運算子管理),而非一般的 Kubernetes Deployment。檢查 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 未啟用。返回「在 Apigee hybrid 中啟用 MCP」,確認 enableMcpServer: true 已設為 overrides.yaml 中的頂層金鑰,且您已在 apigee-org 版本之前升級 apigee-operator Helm 版本。請參閱啟用程序中的步驟 3 和步驟 4,瞭解正確的 helm 指令。

步驟 2:確認 MCP Pod 正在運作

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 是四位數的混合版本修訂版本 (例如混合 1.17.0 的 1170),POD_HASH 則是八個英數字元的尾碼,每個 Pod 的尾碼都不同。

每個 Pod 的 READY 欄都必須顯示 2/2,STATUS 欄則必須顯示 Running。如果 Pod 不是 Running,kubectl -n APIGEE_NAMESPACE describe pod POD_NAME 會顯示原因。常見原因包括圖片提取失敗 (請確認從叢集到 overrides.yaml 中設定的圖片登錄檔的輸出),以及 CPU 或記憶體空間不足 (請提高 overrides.yaml 中的 mcpServer.resources.requests)。

步驟 3:檢查 sidecar 設定提取狀態

每個 MCP Pod 中的 apigee-mcp-server-config 邊車容器會定期從 Apigee 控制層提取 MCP 設定。每次提取作業都會從 apigee.googleapis.com 擷取目前的設定參照,然後從 Cloud Storage 擷取參照的設定套件。提取作業成功完成並取得有效設定後,MCP 資料層就會開始在 https://mcp.apigee.internal/mcp 上提供 MCP 工具流量。

在首次成功提取有效設定之前 (可能是因為尚未為貴組織部署 MCP Discovery Proxy,或 Sidecar 無法連上控制層),MCP Pod 會維持 Ready 狀態,但對 https://mcp.apigee.internal/mcp 的要求會失敗,並顯示「連線遭拒」。

檢查 sidecar 記錄,判斷您屬於哪種情況:

kubectl -n APIGEE_NAMESPACE logs -l app=apigee-mcp-server -c apigee-mcp-server-config --tail=100
  • 重複出現 info 行,表示控制層沒有 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"}
    Apigee 控制層傳回成功回應,但貴組織尚未部署 MCP Discovery Proxy。這是新手上路期間預期的穩定狀態。如要將 MCP 資料層轉換為服務狀態,請按照 MCP 快速入門導覽課程部署 MCP Discovery Proxy。
  • error 行,包含 consecutive_failures 計數器:
    {"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>"}
    Sidecar 記錄是結構化 JSON。如果看到 "level":"error" 且 consecutive_failures 計數器上升,表示 Sidecar 無法完成設定提取。sidecar 會自動重試,並在下次成功提取時將計數器重設為 0。

    如果這個計數器持續上升,請檢查下列常見根本原因:

    • apigee-watcher Google Cloud 服務帳戶不在 Apigee 組織 controlPlaneAccess 資源的 watcher_identities 清單中。請參閱啟用程序中的「步驟 2:將控制層 MCP 設定的存取權授予監控者身分」,瞭解如何新增授權並確認授權已生效。
    • 從叢集輸出至 apigee.googleapis.com 或 storage.googleapis.com 的流量會遭到封鎖。兩個端點都必須可從 MCP Pod 連線 (請參閱啟用程序中的「傳出網路需求」)。
    • apigee-watcher 服務帳戶無法從這個叢集取得 Google Cloud 存取權杖。如果相同命名空間中的現有 Apigee hybrid 元件也回報驗證失敗,請先解決共用驗證問題。
    • 暫時性的 Apigee 控制層或 Cloud Storage 錯誤。如果排除上述原因後,計數器仍持續上升一段時間,請與 Apigee 支援團隊聯絡。

步驟 4:確認已插入訊息處理器 hostAliases

啟用 MCP 時,Apigee 運算子會將一個 hostAliases 項目插入訊息處理器 (MP) Pod 規格。該項目包含一個 IP (MCP 服務 ClusterIP) 和兩個主機名稱: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}'

每個列出的 MP Pod 都必須有 hostAliases 項目,其中包含 mcp.apigee.internal 和小寫 ORG_NAME.mcp.apigee.internal,指向 MCP Service ClusterIP。如果 MP Pod 顯示空白或缺少項目,表示該 Pod 是在啟用 MCP 之前建立。刪除受影響的 MP Pod,讓 ApigeeDeployment 控制器根據目前的 Pod 規格 (包括插入的 hostAliases 項目) 重新建立 Pod:

kubectl -n APIGEE_NAMESPACE delete pod -l app=apigee-runtime

步驟 5:端對端驗證

如要進行端對端測試,透過 MCP 資料層傳送實際的 MCP initialize 要求,請部署 MCP Discovery Proxy,並按照 MCP 快速入門導覽課程操作。在為組織部署 MCP 探索 Proxy 之前,無論訊息處理器是否能連線至 MCP Pod,對 https://mcp.apigee.internal/mcp 的要求都會失敗,並顯示「連線遭拒」 (請參閱步驟 3)。

客服案件

如果您提交的客服案件涉及 Apigee hybrid MCP 資料層,請附上以下輸出內容,加快診斷速度:

  • kubectl -n APIGEE_NAMESPACE logs -l app=apigee-mcp-server --all-containers --tail=1000
  • kubectl -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 是 apigee-org 圖表的 Helm 版本名稱,可透過 helm list -n APIGEE_NAMESPACE | grep apigee-org 找到)。分享 overrides.yaml 前,請先遮蓋機密資料,包括:
    • gcp.workloadIdentity、envs[].serviceAccountPaths 或 mcpServer.serviceAccountPath 下方的任何內嵌服務帳戶金鑰。
    • virtualhosts 下的所有 TLS 憑證或私密金鑰。
    • cassandra.auth 密碼欄位。
    • 覆寫值傳遞給運算子的任何內嵌憑證。
  • 重現問題的完整 curl 指令和回應。

無法在 API Hub 中將 API 樣式變更為 MCP

如果 Apigee API 中心已有 API 資源,且該資源已有 API 作業,則無法將該資源的「API 樣式」屬性變更為「MCP」。如要將 API 註冊為 Apigee API 中心 的 MCP API,請在首次註冊 API 時選取「MCP」MCP樣式,或在將樣式變更為 MCP 前,確認 API 資源中沒有任何作業。

如果遇到其他問題,請參閱「使用偵錯功能」,進一步瞭解如何在 Google Cloud 控制台中使用偵錯工具,分析 MCP 探索 Proxy 的要求和回應。