이 페이지는 Apigee 및 Apigee Hybrid에 적용됩니다.
Apigee Edge 문서 보기
이 페이지에서는 MCP 검색 프록시 배포 문제를 해결하는 방법을 설명합니다. 이 페이지를 사용하여 MCP 배포의 비동기 프로비저닝 수명 주기를 이해하고, 오류 코드를 해결하고, 런타임 연결을 확인할 수 있습니다.
MCP 배포 이해
MCP 탐색 프록시 배포는 프록시 배포가 완료되기 전에 구성이 Apigee 및 Google Cloud 인프라 전반에 완전히 전파되도록 하는 비동기식 다단계 프로세스입니다.
이러한 다운스트림 프로비저닝 단계가 진행되는 동안 UI에는 프록시가 프로비저닝 상태로 표시됩니다. 프로세스가 완료되면 상태가 배포됨으로 변경됩니다. 이 상태는 모든 다운스트림 구성요소가 완전히 프로비저닝되었으며 프록시가 트래픽을 처리할 준비가 되었음을 확인합니다.
문제 해결
다음 섹션에서는 Apigee에서 MCP를 사용하는 동안 발생할 수 있는 오류와 알려진 문제를 설명합니다.
백엔드가 예상 위치에서 도구 인수를 수신하지 않음
문제: 백엔드가 하나의 요청 위치(쿼리 문자열, 헤더 또는 쿠키)에서 도구 인수를 읽지만 OpenAPI 사양이 매개변수 in를 다른 위치로 선언하므로 인수가 백엔드 요청의 다른 위치에 도착합니다. 호출이 실패하거나 인수가 없는 것처럼 작동합니다.
증상: tools/call 요청이 MCP 레이어에서 성공하고 MCP 클라이언트가 인수를 제공하지만 백엔드가 값이 누락된 것처럼 응답합니다(예: 필수 값의 경우 400 또는 전송된 값 대신 기본값이 적용됨).
원인: 매개변수가 OpenAPI 사양에서 in: header 또는 in: cookie로 선언되므로 Apigee는 해당 값을 쿼리 문자열이 아닌 요청 헤더 또는 Cookie 헤더로 전송합니다. 쿼리 문자열에서만 값을 읽는 백엔드에는 이 값이 표시되지 않습니다. 백엔드 요청의 도구 인수 배치를 참고하세요.
해결 방법: 값이 속하는 위치를 결정하고 사양과 백엔드를 일치시킵니다.
- 쿼리 문자열에 값을 유지하려면
in: query매개변수를 선언합니다. - 헤더 또는 쿠키로 전송하려면 선언을 그대로 두고 백엔드의 해당 위치에서 값을 읽습니다.
백엔드가 MCP 클라이언트의 요청에 포함된 쿠키를 수신하지 않음
문제: MCP 클라이언트가 수행하는 HTTP 요청에 도착하는 쿠키(예: 브라우저 기반 클라이언트의 세션 쿠키)가 일부 도구 호출에서 백엔드에 도달하지 않습니다.
증상: 백엔드가 호출자가 인증되지 않았거나 세션에 없는 것처럼 동작하며 동작이 일관되지 않습니다. 동일한 작업이 일부 호출에서는 작동하고 다른 호출에서는 작동하지 않습니다.
원인: 작업에서 하나 이상의 in: cookie 매개변수를 선언하고 영향을 받는 호출에서 이 중 하나 이상을 제공했습니다. Cookie 헤더는 추가되는 것이 아니라 전체적으로 다시 작성되므로 이러한 호출에서는 선언된 쿠키 매개변수만 전달하고 다른 모든 쿠키는 삭제됩니다. 쿠키 매개변수를 제공하지 않은 호출은 헤더를 그대로 전달하므로 일부 호출만 실패합니다. 백엔드 요청의 쿠키를 참조하세요.
해결 방법: 백엔드에 필요한 모든 쿠키를 필요한 각 작업에서 in: cookie 매개변수로 선언하여 해당 값이 클라이언트 요청에서 상속되는 대신 항상 도구 호출에 의해 제공되도록 합니다. 선언되지 않은 쿠키를 보존하는 설정은 없습니다.
도구 호출 및 메타데이터의 오류 응답 상태 코드
Apigee MCP 엔드포인트는 모델 컨텍스트 프로토콜 (MCP) 사양 및 관련 OAuth 표준을 따르는 HTTP 상태 코드를 반환합니다. 이 동작을 이해하면 MCP 클라이언트 또는 AI 에이전트의 오류를 올바르게 처리하는 데 도움이 됩니다.
다음 표에는 Apigee MCP 엔드포인트에서 반환하는 상태 코드가 요약되어 있습니다.
| 시나리오 | HTTP 상태 코드 | 응답 본문 |
|---|---|---|
tools/call에서 도구 실행이 실패합니다 (예: 백엔드 API가 검증 오류 또는 필수 필드 누락과 같은 4xx 또는 5xx 오류를 반환함). |
200 OK |
result.isError가 true로 설정되고 오류 세부정보가 content에 있는 CallToolResult입니다. 이렇게 하면 MCP 클라이언트와 LLM 에이전트가 세션을 종료하는 대신 오류를 읽고 복구할 수 있습니다 (예: 누락된 입력을 다시 요청하고 다시 시도). |
OAuth 보호 리소스 메타데이터 (PRM)가 구성되지 않았거나 /.well-known/oauth-protected-resource/mcp에서 찾을 수 없습니다. |
404 Not Found |
요청된 위치에 보호된 리소스 메타데이터가 없음을 나타냅니다. |
| 액세스 토큰이 누락되었거나 잘못되었거나 만료되었습니다. | 401 Unauthorized |
OAuth 탐색 흐름을 유도하는 WWW-Authenticate 챌린지가 포함됩니다. |
| 액세스 토큰의 범위가 부족합니다. | 403 Forbidden |
승인 승격 흐름을 유도하는 WWW-Authenticate 질문이 포함됩니다. |
예시: 도구 실행 오류 응답 본문
도구 호출이 실패하면 Apigee MCP는 HTTP 200 OK를 반환하고 JSON-RPC result 객체에서 실패를 보고하며 isError는 true로 설정됩니다. 백엔드에서 반환된 원래 오류는 보존됩니다. 백엔드 응답 본문은 result.content[].text에 문자열로 그대로 배치됩니다. 예를 들어 백엔드가 본문 {"error":"User 42 not found"}과 함께 HTTP 404를 반환하는 경우 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 클라이언트는 HTTP 상태 코드가 아닌 result.isError를 검사하여 실패한 도구 호출을 감지해야 합니다. 클라이언트 코드가 도구 실행 오류를 알리기 위해 4xx 또는 5xx HTTP 상태를 구체적으로 예상하는 경우 오류를 감지하지 않습니다. 응답이 HTTP 200 OK이기 때문입니다. result.isError 및 content 배열을 읽도록 이러한 클라이언트를 업데이트합니다.
프로토콜 수준 오류 (예: 잘못된 형식의 JSON-RPC 요청)는 도구 실행 오류와 구별됩니다. 이러한 오류는 result.isError가 아닌 JSON-RPC error 객체 (예: {"jsonrpc": "2.0", "error": {"code": -32700, ...}})로 계속 반환됩니다.
권장사항: 표준을 준수하는 MCP 클라이언트는 기본 로직을 통해 이러한 상태 코드를 처리하므로 변경할 필요가 없습니다. 이전에 비표준 상태 코드를 처리하기 위해 클라이언트 측 해결 방법을 추가한 경우(예: tools/call 오류에 대해 2xx가 아닌 응답 본문을 파싱하거나 PRM 엔드포인트의 500 응답을 '메타데이터가 구성되지 않음'으로 처리) 해당 해결 방법을 삭제하는 것이 좋습니다. 그렇지 않으면 클라이언트가 수정된 상태 코드를 정상적으로 처리하는 대신 오래된 처리 로직을 계속 사용할 수 있습니다.
브라우저 기반 MCP 호출을 위한 CORS 정책
브라우저에서 Apigee MCP 호출이 직접 이루어지는 경우 (예: MCP 검사기가 '프록시를 통해' 대신 '직접' 설정을 사용하는 경우) 교차 출처 리소스 공유(CORS) 정책이 필요합니다. MCP 검색 프록시 템플릿에는 브라우저 기반 호출을 사용 설정하기 위해 기본적으로 프록시 번들의 프록시 엔드포인트 요청 PreFlow에 Apigee CORS 정책이 포함되어 있습니다.
브라우저에서 직접 호출할 때 CORS 관련 문제가 발생하면 MCP 검색 프록시 번들의 프록시 엔드포인트 요청 PreFlow에서 CORS 정책 설정을 조정해야 할 수 있습니다.
MCP 엔드포인트에 요청을 전송할 때 JSON 파싱 오류 발생
MCP 엔드포인트에 요청을 전송할 때 다음과 유사한 오류 메시지(또는 다른 오류 코드 및 메시지)가 표시될 수 있습니다.
{
"error": {
"code": -32700,
"message": "JSON parse error"
},
"id": null,
"jsonrpc": "2.0"
}이 경우 다음 정보를 확인하는 것이 좋습니다.
- 올바른 MCP 엔드포인트 URL을 입력했습니다.
- 요청 형식이 올바릅니다.
- 지원되는 메서드에 액세스하고 있습니다.
- 지원되는 지역에서 MCP 검색 프록시를 사용 설정하고 구성했습니다. 용량 제한이 있을 수 있는 리전 목록은 배포 실패를 참고하세요.
배포 실패
MCP 검색 프록시 배포가 UI에서 실패 상태로 실패하면 오류 메시지에서 자세한 내용을 확인하세요. 일반적인 오류는 다음과 같습니다.
- 네트워킹 구성 실패 또는 OAS의 지원되지 않는 스키마: 이러한 오류는 일반적으로 OpenAPI 사양에 문제가 있음을 나타냅니다. 사양이 유효하고 지원되는 버전을 사용하는지 확인합니다.
- 리전 용량 한도 (Apigee만 해당): 부하 분산기 프로비저닝 실패와 관련된 오류가 표시되거나 프로비저닝 상태가 배포됨으로 변경되지 않는 경우 다음 리전 중 하나에서 일시적인 인프라 용량 한도 때문일 수 있습니다.
asia-east2asia-northeast3asia-southeast2australia-southeast1europe-central2europe-west12europe-west9me-central2us-central2
이 오류를 해결하려면 다른 리전의 환경에 프록시를 배포해 보세요. 이 오류 모드는 런타임 인프라가 자체 클러스터인 Apigee Hybrid에는 적용되지 않습니다.
- 클러스터에서 MCP가 사용 설정되지 않음 (Apigee Hybrid만 해당): MCP 프록시 배포가 무기한으로 프로비저닝 상태로 유지되고 배포됨 상태에 도달하지 않으면 클러스터에서 MCP가 사용 설정되어 있는지 확인합니다. 아래의 클러스터 측 진단을 참조하세요.
클러스터 측 진단 (Apigee Hybrid만 해당)
Apigee Hybrid MCP 데이터 영역은 자체 Kubernetes 클러스터 내에서 실행되므로 클러스터 내 오류 모드는 클러스터에 대해 kubectl로 진단됩니다.
다음 진단 체크리스트를 순서대로 진행합니다.
1단계: 클러스터에서 MCP가 사용 설정되어 있는지 확인
MCP는 일반 Kubernetes Deployment가 아닌 ApigeeDeployment 커스텀 리소스 (Apigee Operator에서 관리)로 배포됩니다. 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 출시를 업그레이드했는지 확인합니다. 올바른 helm 명령어에 대한 사용 설정 절차의 3단계 및 4단계를 참조하세요.
2단계: MCP 포드가 실행 중인지 확인
kubectl -n APIGEE_NAMESPACE get pods -l app=apigee-mcp-server
예상 출력 (포드 서픽스는 다를 수 있음):
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
포드 이름은 apigee-mcp-server-default-ORG_CR_SUFFIX-REV-POD_HASH 템플릿을 따릅니다. 여기서 REV은 4자리 하이브리드 출시 버전 버전 (예: 하이브리드 1.17.0의 경우 1170)이고 POD_HASH은 포드마다 다른 8자 영숫자 서픽스입니다.
모든 포드는 READY 열에 2/2, STATUS 열에 Running를 표시해야 합니다. 포드가 Running가 아니면 kubectl -n APIGEE_NAMESPACE describe pod POD_NAME에 이유가 표시됩니다. 일반적인 원인은 이미지 가져오기 실패 (클러스터에서 overrides.yaml에 구성된 이미지 레지스트리로의 이그레스 확인) 및 CPU 또는 메모리 여유 공간 부족 (overrides.yaml에서 mcpServer.resources.requests 증가)입니다.
3단계: 사이드카 구성 가져오기 상태 확인
각 MCP 포드의 apigee-mcp-server-config 사이드카 컨테이너는 Apigee 컨트롤 플레인에서 MCP 구성을 주기적으로 가져옵니다. 각 가져오기는 apigee.googleapis.com에서 현재 구성 참조를 가져온 다음 Cloud Storage에서 참조된 구성 번들을 가져옵니다. 유효한 구성으로 가져오기가 완료되면 MCP 데이터 영역이 https://mcp.apigee.internal/mcp에서 MCP 도구 트래픽을 제공하기 시작합니다.
유효한 구성으로 첫 번째 가져오기가 성공하기 전에는 (조직에 MCP 탐색 프록시가 아직 배포되지 않았거나 사이드카가 컨트롤 플레인에 도달할 수 없기 때문) MCP 포드가 Ready 상태로 유지되지만 https://mcp.apigee.internal/mcp에 대한 요청은 연결 거부됨으로 실패합니다.
사이드카 로그를 검사하여 어떤 경우에 해당하는지 확인합니다.
kubectl -n APIGEE_NAMESPACE logs -l app=apigee-mcp-server -c apigee-mcp-server-config --tail=100
- 컨트롤 플레인에서 MCP 구성이 없음을 나타내는
info줄 반복: Apigee 컨트롤 플레인이 성공 응답을 반환했지만 조직에 MCP 검색 프록시가 아직 배포되지 않았습니다. 이는 온보딩 중에 예상되는 안정적인 상태입니다. 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"} consecutive_failures카운터가 있는error줄: 사이드카 로그는 정형 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>"}consecutive_failures카운터가 증가하는"level":"error"가 표시되면 사이드카가 구성 가져오기를 완료할 수 없습니다. 사이드카는 백오프를 사용하여 자동으로 다시 시도하고 다음 가져오기가 성공하면 카운터를 0으로 재설정합니다.이 카운터가 계속 증가할 때 확인해야 할 일반적인 근본 원인은 다음과 같습니다.
apigee-watcherGoogle Cloud 서비스 계정이 Apigee 조직의controlPlaneAccess리소스에 있는watcher_identities목록에 없습니다. 사용 설정 절차의 2단계: 컨트롤 플레인의 MCP 구성에 대한 감시자 ID 액세스 권한 부여를 참조하여 권한 부여를 추가하고 적용되었는지 확인합니다.- 클러스터에서
apigee.googleapis.com또는storage.googleapis.com로의 이그레스가 차단됩니다. 두 엔드포인트 모두 MCP 포드에서 연결할 수 있어야 합니다 (사용 설정 절차의 아웃바운드 네트워크 요구사항 참조). apigee-watcher서비스 계정은 이 클러스터에서 Google Cloud 액세스 토큰을 가져올 수 없습니다. 동일한 네임스페이스의 기존 Apigee Hybrid 구성요소에서도 인증 실패가 보고되는 경우 공유 인증 문제를 먼저 해결합니다.- 일시적인 Apigee 컨트롤 플레인 또는 Cloud Storage 오류입니다. 위의 원인을 배제한 후에도 카운터가 장기간 계속 상승하면 Apigee 지원팀에 문의하세요.
4단계: 메시지 프로세서 hostAliases가 삽입되었는지 확인
MCP를 사용 설정하면 Apigee 연산자가 메시지 프로세서(MP) 포드 사양에 hostAliases 항목 하나를 삽입합니다. 이 항목에는 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 포드에는 MCP 서비스 ClusterIP를 가리키는 mcp.apigee.internal 및 소문자 ORG_NAME.mcp.apigee.internal가 모두 포함된 hostAliases 항목이 있어야 합니다. 비어 있거나 누락된 항목을 표시하는 MP 포드는 MCP가 사용 설정되기 전에 생성되었습니다. ApigeeDeployment 컨트롤러가 현재 포드 사양 (삽입된 hostAliases 항목 포함)에서 다시 만들도록 영향을 받는 MP 포드를 삭제합니다.
kubectl -n APIGEE_NAMESPACE delete pod -l app=apigee-runtime
5단계: 엔드 투 엔드 인증
MCP 데이터 영역을 통해 실제 MCP initialize 요청을 전송하는 엔드 투 엔드 테스트의 경우 MCP 탐색 프록시를 배포하고 MCP 빠른 시작을 따르세요.
조직에 MCP 검색 프록시가 배포되기 전에는 메시지 프로세서가 MCP 포드에 도달할 수 있는지 여부에 관계없이 https://mcp.apigee.internal/mcp에 대한 요청이 연결 거부됨으로 실패합니다 (3단계 참고).
지원 케이스
Apigee Hybrid MCP 데이터 영역과 관련된 지원 케이스를 여는 경우 다음 출력을 첨부하여 진단 속도를 높이세요.
kubectl -n APIGEE_NAMESPACE logs -l app=apigee-mcp-server --all-containers --tail=1000kubectl -n APIGEE_NAMESPACE describe pod -l app=apigee-mcp-serverkubectl -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 허브에서 API 스타일을 MCP로 변경할 수 없음
기존 API 작업이 있는 API 리소스가 Apigee API 허브에 이미 있는 경우 해당 리소스의 API 스타일 속성을 MCP로 변경할 수 없습니다. Apigee API 허브에 API를 MCP API로 등록하려면 API를 처음 등록할 때 MCP 스타일을 선택하거나 스타일을 MCP로 변경하기 전에 API 리소스에 작업이 없는지 확인해야 합니다.
다른 문제가 발생하면 디버그 사용을 참고하여 Google Cloud 콘솔에서 디버그 도구를 사용하여 MCP 검색 프록시와의 요청 및 응답을 분석하는 방법에 관한 자세한 내용을 확인하세요.