Repository navigation
docs(mcp): APIM·Toolbox·IQ 활용과 선택 가이드 - #62
Conversation
Add a reproducible private Azure MCP lab with Entra user delegation, native APIM REST-to-MCP tools, and separately authenticated upstream servers. Preserve sanitized live evidence, architecture SVGs, review corrections, and explicit verification limits. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Critical authentication and proxy findings, plus unresolved moderate correctness and cleanup issues, remain.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR adds an Azure MCP lab covering Entra OBO, APIM REST-to-MCP conversion, Learn proxying, private networking, and validation evidence.
Changes:
- Adds MCP services, authentication/OBO flows, probes, evidence tooling, and tests.
- Adds APIM, ACA, AKS, networking, identity, and cleanup infrastructure.
- Adds guides, research, case documentation, diagrams, captures, and taxonomy entries.
Open findings remain: one documentation status nit, five moderate implementation findings, and two critical authentication/proxy findings.
File summaries
| File | Reviewed change |
|---|---|
samples/azure-api-management/mcp-entra-lab/transport_proxy.py |
Implements the HTTPS CONNECT proxy; critical listener exposure remains. |
samples/azure-api-management/mcp-entra-lab/tests/test_upstream_probe.py |
Tests upstream probe validation. |
samples/azure-api-management/mcp-entra-lab/tests/test_transport_proxy.py |
Tests proxy relay and allowlisting. |
samples/azure-api-management/mcp-entra-lab/tests/test_service_rest.py |
Tests REST routes, authentication, and OBO. |
samples/azure-api-management/mcp-entra-lab/tests/test_service_regressions.py |
Tests security regressions. |
samples/azure-api-management/mcp-entra-lab/tests/test_service_obo.py |
Tests OBO behavior. |
samples/azure-api-management/mcp-entra-lab/tests/test_service_helpers.py |
Provides service test helpers. |
samples/azure-api-management/mcp-entra-lab/tests/test_service_fakes.py |
Provides service test doubles. |
samples/azure-api-management/mcp-entra-lab/tests/test_service_config.py |
Tests configuration validation. |
samples/azure-api-management/mcp-entra-lab/tests/test_service_auth.py |
Tests token validation. |
samples/azure-api-management/mcp-entra-lab/tests/test_service_arm.py |
Tests ARM access and sanitization. |
samples/azure-api-management/mcp-entra-lab/tests/test_probe_utils.py |
Tests probe utilities. |
samples/azure-api-management/mcp-entra-lab/tests/test_probe_cloud.py |
Tests cloud probes. |
samples/azure-api-management/mcp-entra-lab/tests/test_network_probe.py |
Tests network probe deployment. |
samples/azure-api-management/mcp-entra-lab/tests/test_native_gate.py |
Tests native caller restrictions. |
samples/azure-api-management/mcp-entra-lab/tests/test_evidence.py |
Tests evidence handling. |
samples/azure-api-management/mcp-entra-lab/tests/test_entra_setup.py |
Tests Entra setup. |
samples/azure-api-management/mcp-entra-lab/tests/test_cloud_stage.py |
Tests staged deployment. |
samples/azure-api-management/mcp-entra-lab/tests/test_cloud_lab.py |
Tests lab safeguards. |
samples/azure-api-management/mcp-entra-lab/tests/test_cleanup.py |
Tests cleanup behavior. |
samples/azure-api-management/mcp-entra-lab/tests/test_auth_probe.py |
Tests authentication probes. |
samples/azure-api-management/mcp-entra-lab/tests/conftest.py |
Configures the test suite. |
samples/azure-api-management/mcp-entra-lab/service/tools.py |
Registers MCP tools. |
samples/azure-api-management/mcp-entra-lab/service/rest.py |
Registers REST routes; critical authentication middleware issue remains. |
samples/azure-api-management/mcp-entra-lab/service/obo.py |
Implements OBO exchanges. |
samples/azure-api-management/mcp-entra-lab/service/learn.py |
Connects to Learn MCP; discovery error translation issue remains. |
samples/azure-api-management/mcp-entra-lab/service/inventory.py |
Defines fixture inventory. |
samples/azure-api-management/mcp-entra-lab/service/config.py |
Validates runtime configuration; port validation issue remains. |
samples/azure-api-management/mcp-entra-lab/service/auth.py |
Implements token authentication. |
samples/azure-api-management/mcp-entra-lab/service/arm.py |
Reads and sanitizes ARM results. |
samples/azure-api-management/mcp-entra-lab/service/app.py |
Builds the ASGI application. |
samples/azure-api-management/mcp-entra-lab/service/__init__.py |
Defines the service package. |
samples/azure-api-management/mcp-entra-lab/requirements.txt |
Pins Python dependencies. |
samples/azure-api-management/mcp-entra-lab/README.md |
Documents lab setup and validation. |
samples/azure-api-management/mcp-entra-lab/probe_utils.py |
Provides probe helpers. |
samples/azure-api-management/mcp-entra-lab/probe_upstreams.py |
Probes upstream MCP services. |
samples/azure-api-management/mcp-entra-lab/probe_native_gate.py |
Probes native caller restrictions. |
samples/azure-api-management/mcp-entra-lab/package.json |
Defines Node tooling. |
samples/azure-api-management/mcp-entra-lab/package-lock.json |
Locks Node dependencies. |
samples/azure-api-management/mcp-entra-lab/network_probe.py |
Deploys the private network probe. |
samples/azure-api-management/mcp-entra-lab/mcp.example.json |
Provides client configuration examples. |
samples/azure-api-management/mcp-entra-lab/infra/private-dns.bicep |
Defines private DNS resources. |
samples/azure-api-management/mcp-entra-lab/infra/policies/remove-upstream-token.xml |
Removes upstream bearer tokens. |
samples/azure-api-management/mcp-entra-lab/infra/policies/metadata.xml |
Serves protected-resource metadata. |
samples/azure-api-management/mcp-entra-lab/infra/policies/global.xml |
Defines APIM authentication policy; REST metadata mapping issue remains. |
samples/azure-api-management/mcp-entra-lab/infra/native-auth.bicep |
Configures native authentication. |
samples/azure-api-management/mcp-entra-lab/infra/foundation.bicep |
Defines lab foundation resources; cluster-admin scope issue remains. |
samples/azure-api-management/mcp-entra-lab/infra/entry.bicep |
Defines the deployment entrypoint. |
samples/azure-api-management/mcp-entra-lab/infra/apps.bicep |
Deploys MCP applications. |
samples/azure-api-management/mcp-entra-lab/infra/apim.bicep |
Configures APIM APIs and mappings. |
samples/azure-api-management/mcp-entra-lab/evidence/upstreams.json |
Stores sanitized upstream evidence. |
samples/azure-api-management/mcp-entra-lab/evidence/native-client-gate.json |
Stores native-gate evidence. |
samples/azure-api-management/mcp-entra-lab/evidence/auth-local-live.json |
Stores sanitized authentication evidence. |
samples/azure-api-management/mcp-entra-lab/evidence.py |
Sanitizes and renders evidence. |
samples/azure-api-management/mcp-entra-lab/Dockerfile |
Defines the service image. |
samples/azure-api-management/mcp-entra-lab/cloud_stage.py |
Manages application stages. |
samples/azure-api-management/mcp-entra-lab/cloud_lab.py |
Manages the isolated lab. |
samples/azure-api-management/mcp-entra-lab/cleanup.py |
Implements cleanup; missing service-principal handling issue remains. |
samples/azure-api-management/mcp-entra-lab/auth_probe.py |
Validates tokens and OBO. |
samples/azure-api-management/mcp-entra-lab/.dockerignore |
Restricts the build context. |
docs/research/azure-api-management/mcp-authentication-options/images/local-upstreams.svg |
Illustrates local upstream boundaries. |
docs/research/azure-api-management/mcp-authentication-options/images/functions-alternative.svg |
Illustrates Functions hosting. |
docs/research/azure-api-management/mcp-authentication-options/images/container-apps-obo.svg |
Illustrates ACA OBO. |
docs/research/azure-api-management/mcp-authentication-options/images/app-service-alternative.svg |
Illustrates App Service hosting. |
docs/research/azure-api-management/mcp-authentication-options/images/apim-rest-tools.svg |
Illustrates APIM REST-to-MCP. |
docs/research/azure-api-management/mcp-authentication-options/images/apim-existing-mcp.svg |
Illustrates MCP proxying. |
docs-taxonomy.yml |
Registers documentation taxonomy entries. |
Review details
Files not reviewed (1)
- samples/azure-api-management/mcp-entra-lab/package-lock.json: Generated file
Suppressed comments (5)
docs/guides/azure-api-management/mcp-entra-private-access/index.md:9
- This page is marked
verifiedeven though the linked lab and case still record an unresolved APIM preview endpoint/backend contract conflict (for example, the lab documents the array-versus-keyed-object discrepancy at line 216). The repository documentation contract requiresneeds-reviewwhenever a material source conflict remains, so this status should not claim complete verification until that conflict is resolved or the guide removes the affected claim.
verification_status: verified
samples/azure-api-management/mcp-entra-lab/cleanup.py:46
- Cleanup assumes every recorded application already has a
service_principal_id, butentra_setup.ensure_app()persists the application record beforeensure_sp()runs. If setup is interrupted in that window, or if a prior delete succeeded before its state flag was saved, this direct lookup/GET raises instead of deleting the owned app or resource group, defeating the documented resumable cleanup flow. Handle missing/already-deleted service principals idempotently (for example, discover byappIdand treat 404 as already removed) before proceeding with the group deletion.
if not record.get("cleanup_sp_deleted"):
principal = directory.request(
"get", f"/servicePrincipals/{record['service_principal_id']}"
)
if principal["appId"] != record["client_id"]:
raise ValueError("service principal does not match its recorded lab application")
samples/azure-api-management/mcp-entra-lab/infra/foundation.bicep:237
- This role ID is Azure Kubernetes Service RBAC Cluster Admin, which grants full control of every Kubernetes resource in the new cluster. The later
--access-level readonlyflag only constrains the AKS MCP process and cannot limit the operator's kubeconfig, so the sample's read-only/security boundary is undermined after deployment. Prefer a narrowly scoped bootstrap/namespace role for the probe, or explicitly document this persistent cluster-admin grant as a lab prerequisite.
samples/azure-api-management/mcp-entra-lab/infra/policies/global.xml:23 - This global error branch also applies to the protected
lab-restAPI, but the ternary maps every API other thanlearn-mcpto therest-toolsMCP resource. A direct unauthenticated/rest/inventorytherefore receives aresource_metadataURL for a different resource, while no REST metadata mapping is defined. Exclude the REST API from this MCP-specific header or provide a distinct REST mapping.
samples/azure-api-management/mcp-entra-lab/service/config.py:77 _require_https_urlchecksparts.hostnamebut never evaluatesparts.port, so a value such ashttps://host:not-a-port/mcppasses configuration loading and only fails later when the SDK parsesresource_server_url. Validate the port inside this boundary so malformed resource URLs consistently raiseConfigError.
- Files reviewed: 68/80 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Replace custom deployment and test/probe runners with native azd provisioning, ACR remote builds and explicit MCP client scenarios. Rewrite customer-facing terminology, retain only runtime code, and capture fresh command responses after removing and rebuilding the Azure environment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve the upstream navigation and local-state rules, retain both publication safety checks, and store curated public responses separately from local evidence. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved runtime, configuration, credential-lifecycle, and validation issues remain.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (6)
docs/guides/azure-api-management/mcp-entra-private-access/index.md:9
verification_status: verifiedis too strong for this page as written:applies_toand the body make version-specific claims about MCP Python SDK 2.2.0 and Inspector 2.5.0, butofficial_sourceslists neither MCP project's canonical source. Add and verify those sources (as the neighboring research page does for the Python SDK), or keep this page atneeds-reviewso the metadata does not claim unsupported verification.
verification_status: verified
docs/labs/azure-api-management/mcp-rest-and-upstream/index.md:32
- This page is explicitly marked
verification_status: needs-review, butlast_verifiedstill publishes a date that reads as a completed verification. The source-verification contract distinguishes incomplete review from verified claims; remove thislast_verifiedfield (or change the status only after every material claim has been checked) so the metadata does not overstate verification.
last_verified: 2026-09-13
samples/azure-api-management/mcp-entra-lab/README.md:56
- The README compresses the 401/403 check and cleanup into item 8, while the linked walkthrough and PR description define cleanup as scenario 9. This makes the sample entry point advertise eight scenarios and leaves the walkthrough numbering inconsistent; split the final item into separate 8 and 9 entries.
8. Check 401/403 behavior and remove the environment when finished.
samples/azure-api-management/mcp-entra-lab/scripts/identity.py:183
- This creates a client secret that expires after two days, but
preparehas no rotation path: oncesecretExpiresAtis reached it raises and redeployment cannot refresh the credential. The walkthrough keeps the environment for later scenarios, so users returning after two days are left to edit private state manually; add an explicit rotation flow or document a supported renewal procedure before relying on this credential.
samples/azure-api-management/mcp-entra-lab/service/tools.py:72 OboError.safe_codeis not limited to consent failures:_safe_failure_codealso returns values such asinvalid_client,server_error,invalid_scope, andAuthorizationFailed. Prefixing every one withConsentRequiredmisdiagnoses bad credentials and transient/server failures for tool callers; use a neutral prefix or map only consent-specific codes.
scripts/docs/validate_public_safety.py:114- The no-Git fallback still recursively includes
.azure, so running this validator from a source archive or another checkout without.gitwill inspect private azd state and can fail on a normal local environment. Apply the same.azureexclusion in this branch; the Git-aware branch already skips ignored state while still seeing force-added files.
- Files reviewed: 46/58 changed files
- Comments generated: 3
- Review effort level: Lite
Make the end-to-end walkthrough the primary customer document, with architecture and authentication context, in-place diagrams and actual response captures. Reframe the remaining documents as optional detailed references and point them back to the unified guide. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Compare direct MCP hosting, managed Toolbox, REST conversion and optional API gateways. Move the main guide to Azure Architecture, add a standalone Toolbox azd example and diagrams, and distinguish source-verified Toolbox guidance from existing live ACA/APIM captures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
관리 gateway, hosted agent runtime, Toolbox 탐색과 backend 호스팅을 구분하고 MCP protocol 변경을 부록으로 정리합니다. 실행 시나리오와 캡처는 samples로 옮기며 기존 리뷰의 URL 예외와 직접 의존성도 보완합니다. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve the published branch history and verify the updated site pipeline with the MCP documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
서비스와 핵심 기능을 소개하고 APIM과 Toolbox의 protocol·OAuth·OBO 근거를 구분합니다. IQ 통합, 공식 토큰 비교 영상, 단순한 SVG와 실제 실행 기록 링크를 추가합니다. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Integrate main's topic-package publishing layout. Keep the MCP guide, references, validation case and azd samples together, retain old URLs as redirects, and preserve ignored local deployment state. Adapt the existing docs checks to the added topic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
사전 token 연결과 자동 OAuth, downstream OBO를 분리합니다. 기존 환경의 discovery·PKCE 선언·resource URI·token 검증·OBO를 재확인하고 공개용 결과와 수동 절차를 연결합니다. 본문 줄글은 표와 짧은 목록으로 정리합니다. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Entra의 Authorization Code와 PKCE 지원을 명확히 하고 MCP Server/APIM의 PRM 제공 및 JWT 검증과 분리합니다. Metadata 관측은 제품 미지원 판정이 아닌 client 상호운용성 노트로 유지합니다. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Integrate the current main branch, use practical purpose/subject tags for MCP documents, and keep one canonical copy of the walkthrough images. Update repository-count expectations for the MCP topic without changing discovery behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
새 터미널에서 실습 kubeconfig 경로를 명시하고 검증해 기본 클러스터로의 잘못된 연결을 방지합니다. 공개 Entra/APIM 계약을 기준으로 API 앱과 client 앱, v2 token claims, PRM 및 JWT 정책 구성을 명확히 합니다. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
HTTP MCP tools와 Entra 인증의 지원 구성, 목적별 읽기 경로와 완료 기준을 안내합니다. 실험 범위 설명은 사례에 유지하고 본문 중복·미확인 중심 비교를 줄이며 명시적인 제품 제약을 정리합니다. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
APIM과 Toolbox의 서비스 정의, 활용 상황, 핵심 기능을 본문에 설명합니다. 인증은 통제 지점과 사용자 권한으로 요약하고 상세 구성도와 완료 기준은 인증 참고로 연결해 실증 예제와 중복을 줄입니다. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
임시 인증 설정 변경 전에 EXIT trap을 등록하고 원래 실패 코드를 유지합니다. 복구 오류를 표시하고 고유 백업과 새 셸의 수동 복구 절차를 제공하며 다른 환경의 백업 적용을 차단합니다. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
고객용 대표 문서
Azure MCP 구성 — APIM·Toolbox·IQ의 활용과 선택 기준을 대표 문서로 정리했습니다.
앞부분은 각 서비스가 무엇이며 왜 사용하는지에 집중합니다. APIM은 여러 팀의 API/MCP에 공통 운영 정책을 적용하고, Toolbox는 client별 도구 연결·인증·변경 관리를 줄이며, IQ는 조직의 업무 데이터와 지식을 연결합니다.
서비스 정의·도입 이유·핵심 기능을 복원하고 APIM과 Toolbox 구성도를 유지했습니다. 인증은 본문에서 짧게 요약하며, 앱 등록·claims·PRM·완료 기준과 인증 구성도는 인증 상세 문서로 이동했습니다. 본문 인증 절은 60줄에서 12줄로 줄였습니다.
이번 구조 변경
verified로 정리했습니다.2026-07-28protocol의 session·handshake 제거, 요청별 metadata, SSE 유지, OAuth discovery·PKCE·등록 요구사항을 공식 규격과 대조했습니다. SDK/제품2.x, JSON-RPC 2.0과 구분합니다.aud·azp·scp와 JWT 정책의required-claims위치를 정리했습니다.MCP HTTP auth 단계별 추가 확인
Entra의 Authorization Code + PKCE 지원, MCP Server/APIM의 PRM 제공·JWT 검증, downstream OBO를 구분했습니다. MSAL interactive flow의 자동 PKCE는 공식 문서로 확인했습니다. 기존 RG·Entra 앱은 읽기 전용으로 재확인했으며 리소스/인증 설정은 변경하지 않았습니다.
complete·isError: falseapi://...만 등록. Canonical URL 대상 CLI token 요청AADSTS500011수동 확인 절차와 비식별 결과를 추가했습니다. 현재 RG에는 Foundry/Toolbox가 없어 그 부분은 문서 근거와 미실측 범위를 표시합니다.
APIM과 Toolbox의 조합은 요구사항에 따른 설계 제안으로 별도 표시했습니다. 새 Foundry/IQ 배포, Toolbox 사용자 OAuth의 실증 또는 자체 토큰 절감 측정을 수행했다고 주장하지 않습니다. 아래 실제 실행 결과와 구분합니다.
Topic package와 실행 방식
최신 main의 #64 게시 구조를 반영해 대표 문서·인증 참고·호스팅 참고·실행 사례와 두 sample을
docs/services/azure-architecture/mcp-configuration/에 모았습니다. 이전 guide/lab/case/research URL은 redirect로 보존합니다. 두 sample에는sample.yml을 추가했고,.azure·.private의 로컬 배포 상태는 비공개로 보존했습니다.#65의 목적/주제 태그와 자산 단일 원본 규칙도 반영했습니다. Sample의 중복 이미지 9개는 같은 topic의 사례·참고 문서 원본으로 링크를 바꿨으며, 실행 명령과 이미지 내용은 유지했습니다.
azure.yaml과 Bicep 기반 native azd로 provisioning, ACR remote build, Container App service deployment를 수행합니다.azd, MCP Inspector,curl,kubectl명령을 직접 실행합니다. 기존 실행 명령·요청 예제 33개를 이동 전후 비교해 보존했습니다.새 환경에서 실행한 내용
기존 실습 RG, AKS·Container Apps 관리 RG와 Entra 앱 3개를 제거한 뒤 새 azd environment를 배포했습니다.
azd provision --previewazd upgetInventoryMCP tool에서 같은 가상 재고 반환2026-07-28, RG 존재·region·상태 반환공개용 응답 발췌는
docs/services/azure-architecture/mcp-configuration/samples/apim-entra-lab/assets/captures/2026-09-13-responses.json에 있습니다. 원본 실행 로그, token·환경 식별자는 공개하지 않습니다.검증 및 리뷰 대응
KUBECONFIG가 유실되는 리뷰를 반영했습니다. 절대 경로를 재입력하고 빈 값·상대 경로·없는 파일을 거부하며, 새 셸과 공백 포함 경로 등 5개 조건을 확인했습니다.mcp와 Toolbox의 두 service를 인식하는지 확인httpx2를 직접 의존성으로 명시하고 잘못된 URL의 예외를ConfigError로 통일mcp 2.2.0이 원래httpx2>=2.5.0을 요구한다는 점을 확인; service import와 정상 URL 2개·오류 URL 8개 확인.azure/는 제외하지만 실수로 force-add한 파일은 계속 검사합니다.검토 사항