From 5c069a0ee7992f0515173162ee69ac0c00f43514 Mon Sep 17 00:00:00 2001 From: koseokmin Date: Sat, 22 Aug 2026 21:23:29 +0900 Subject: [PATCH] =?UTF-8?q?Portal=20registry=20ADR=EC=9D=98=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=EB=A5=BC=200013=EC=9C=BC=EB=A1=9C=20=EC=98=AE?= =?UTF-8?q?=EA=B8=B4=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit main이 6078852의 endpoint 소유권 반전을 ADR-0010으로 기록하면서 이 브랜치의 ADR-0010과 번호가 겹쳤다. 두 문서는 다른 결정이므로 나중에 문서를 합칠 때 한쪽을 옮겨야 한다. 이 브랜치가 0012까지 쓰고 있어 0011·0012를 건드리지 않는 첫 번호인 0013을 쓴다. 파일명과 제목, 대체 관계를 가리키는 ADR-0007·ADR-0009, 결정 목록, architecture 문서, Portal 계약 문서, Helm 설명, 그리고 application.yml 주석의 참조를 함께 바꾼다. 결정 내용은 바뀌지 않는다. Co-Authored-By: Claude Opus 5 --- deploy/README.md | 2 +- deploy/helm/mcp-server/values.yaml | 2 +- docs/architecture.md | 2 +- docs/contracts/portal-mcp/README.md | 2 +- docs/contracts/portal-mcp/protocol-v0.1-registry.md | 2 +- docs/decisions/ADR-0007-one-mcp-per-tool-service.md | 6 +++--- .../decisions/ADR-0009-container-handles-public-mcp-path.md | 2 +- ... => ADR-0013-portal-owns-route-and-endpoint-registry.md} | 2 +- docs/decisions/README.md | 2 +- src/main/resources/application.yml | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) rename docs/decisions/{ADR-0010-portal-owns-route-and-endpoint-registry.md => ADR-0013-portal-owns-route-and-endpoint-registry.md} (99%) diff --git a/deploy/README.md b/deploy/README.md index 0353fc1..8796fc4 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -3,7 +3,7 @@ 이 디렉터리는 **배포될 대상**을 정의한다. 빌드·이미지·배포 실행 방식은 사내 표준 CI/CD가 담당하며 이 저장소가 정하지 않는다. -> **내부망 운영은 이 Chart를 사용하지 않는다**([ADR-0010](../docs/decisions/ADR-0010-portal-owns-route-and-endpoint-registry.md) 결정 7). +> **내부망 운영은 이 Chart를 사용하지 않는다**([ADR-0013](../docs/decisions/ADR-0013-portal-owns-route-and-endpoint-registry.md) 결정 7). > 여기 정의된 토폴로지는 배포 하나가 Tool Service 하나를 보는 `mcp.bundles` 구성(ADR-0007/0009)을 전제한다. > 내부망 운영은 endpoint 목록과 route 매핑의 원천을 Portal로 옮겼고, 배포 하나가 N개 route를 서비스한다. > diff --git a/deploy/helm/mcp-server/values.yaml b/deploy/helm/mcp-server/values.yaml index ce7611f..1388a3e 100644 --- a/deploy/helm/mcp-server/values.yaml +++ b/deploy/helm/mcp-server/values.yaml @@ -1,6 +1,6 @@ # 환경 공통 기본값과 배포 토폴로지. 환경별 차이는 values-{env}.yaml이 덮어쓴다. # -# 내부망 운영은 이 Chart를 사용하지 않는다(ADR-0010 결정 7). 아래 원칙과 deployments 목록은 +# 내부망 운영은 이 Chart를 사용하지 않는다(ADR-0013 결정 7). 아래 원칙과 deployments 목록은 # 배포 하나가 Tool Service 하나를 보는 mcp.bundles 구성(ADR-0007/0009)을 전제한다. # Portal이 endpoint 원천인 구성에서는 배포 하나가 N개 route를 서비스하므로 이 토폴로지가 성립하지 않는다. # 자세한 배경은 deploy/README.md 머리말에 있다. diff --git a/docs/architecture.md b/docs/architecture.md index e18fa37..d0fd280 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -210,7 +210,7 @@ Portal Registry를 사용하는 구성에서는 포털을 route별 Tool Server e 이 구성에서 각 배포는 같은 환경 host의 고유 `publicPath`를 가진 OpenShift Route로 노출된다([ADR-0009](decisions/ADR-0009-container-handles-public-mcp-path.md)). Route는 path로 Service만 선택하고 컨테이너가 같은 값을 `mcp.endpoint-path`로 직접 처리한다. Deployment·snapshot·readiness·connection pool은 path별로 분리되고, 공유되는 장애 지점은 OpenShift ingress와 DNS다. -**내부망 운영은 위 구성을 쓰지 않는다.** endpoint 목록과 route↔Tool Service 매핑의 원천을 Portal로 옮기고, 배포 하나가 N개 route를 서비스하며 route 하나에 N개 Tool Service가 붙을 수 있다([ADR-0010](decisions/ADR-0010-portal-owns-route-and-endpoint-registry.md)). 이때 route key는 `mcp.endpoint-path`에 고정되지 않고 `/mcp/{routeKey}` URI에서 결정되며, 카탈로그 병합과 `max-tools-total` 상한은 route 단위로 적용된다. 배포별 분리가 사라지므로 connection pool·thread·재기동 영향은 전 route가 공유하고, readiness는 route 하나만 준비돼도 UP이 된다. 근거와 포기한 것은 ADR-0010에 있다. +**내부망 운영은 위 구성을 쓰지 않는다.** endpoint 목록과 route↔Tool Service 매핑의 원천을 Portal로 옮기고, 배포 하나가 N개 route를 서비스하며 route 하나에 N개 Tool Service가 붙을 수 있다([ADR-0013](decisions/ADR-0013-portal-owns-route-and-endpoint-registry.md)). 이때 route key는 `mcp.endpoint-path`에 고정되지 않고 `/mcp/{routeKey}` URI에서 결정되며, 카탈로그 병합과 `max-tools-total` 상한은 route 단위로 적용된다. 배포별 분리가 사라지므로 connection pool·thread·재기동 영향은 전 route가 공유하고, readiness는 route 하나만 준비돼도 UP이 된다. 근거와 포기한 것은 ADR-0013에 있다. 운영 상태는 외부 ingress가 아니라 management port(기본 9090)의 `GET /actuator/toolBundles`로 확인한다. diff --git a/docs/contracts/portal-mcp/README.md b/docs/contracts/portal-mcp/README.md index a7a9620..a5c0c61 100644 --- a/docs/contracts/portal-mcp/README.md +++ b/docs/contracts/portal-mcp/README.md @@ -17,7 +17,7 @@ Portal ──[portal-mcp 계약]──▶ MCP Server ──[tool-service-mcp 계 Portal이 route별 Tool Server 목록을 관리하는 구성(`mcp.portal.enabled=true`)에서만 사용하며, 이때 Portal은 **endpoint 목록의 원천**이 된다. -**내부망 운영은 이 구성을 채택했다**([ADR-0010](../../decisions/ADR-0010-portal-owns-route-and-endpoint-registry.md)). +**내부망 운영은 이 구성을 채택했다**([ADR-0013](../../decisions/ADR-0013-portal-owns-route-and-endpoint-registry.md)). 따라서 이 계약은 선택 사항이 아니라 운영 경로의 정본이다. 배포 하나가 N개 route를 서비스하고 route 하나에 N개 Tool Service가 붙을 수 있다. diff --git a/docs/contracts/portal-mcp/protocol-v0.1-registry.md b/docs/contracts/portal-mcp/protocol-v0.1-registry.md index 805dd4a..cb5ffdf 100644 --- a/docs/contracts/portal-mcp/protocol-v0.1-registry.md +++ b/docs/contracts/portal-mcp/protocol-v0.1-registry.md @@ -67,7 +67,7 @@ mcp: > route key를 지정하는 설정은 **없다.** route key는 요청 경로에서만 결정되며(`McpRequestContextFactory`), > 설정 기본값으로 보정하지 않는다(§7). 과거 `mcp.portal.route-key`가 선언만 되어 있었으나 -> 어떤 코드도 읽지 않아 제거했다([ADR-0010](../../decisions/ADR-0010-portal-owns-route-and-endpoint-registry.md)). +> 어떤 코드도 읽지 않아 제거했다([ADR-0013](../../decisions/ADR-0013-portal-owns-route-and-endpoint-registry.md)). ## 4. 응답 계약 diff --git a/docs/decisions/ADR-0007-one-mcp-per-tool-service.md b/docs/decisions/ADR-0007-one-mcp-per-tool-service.md index b419ea9..1d4569f 100644 --- a/docs/decisions/ADR-0007-one-mcp-per-tool-service.md +++ b/docs/decisions/ADR-0007-one-mcp-per-tool-service.md @@ -2,12 +2,12 @@ - 상태: Superseded - 결정일: 2026-08-02 -- 대체 결정: [ADR-0010](ADR-0010-portal-owns-route-and-endpoint-registry.md) +- 대체 결정: [ADR-0013](ADR-0013-portal-owns-route-and-endpoint-registry.md) - 관련: [ADR-0001](ADR-0001-stateless-execution-boundary.md), [ADR-0002](ADR-0002-tool-exposure-and-single-call.md), [ADR-0009](ADR-0009-container-handles-public-mcp-path.md), [계약 v0.2](../contracts/tool-service-mcp/protocol-v0.2-bundle-discovery.md) > 이 문서는 당시 검토 이력을 보존한다. 내부망 운영은 endpoint 목록과 route 매핑의 원천을 Portal로 옮겼으므로 -> 현재 구현과 신규 연동에는 [ADR-0010](ADR-0010-portal-owns-route-and-endpoint-registry.md)을 적용한다. -> 아래 격리 논거는 폐기된 것이 아니라 ADR-0010이 무엇을 포기했는지 판단하는 근거로 남는다. +> 현재 구현과 신규 연동에는 [ADR-0013](ADR-0013-portal-owns-route-and-endpoint-registry.md)을 적용한다. +> 아래 격리 논거는 폐기된 것이 아니라 ADR-0013이 무엇을 포기했는지 판단하는 근거로 남는다. 외부에서 여러 MCP를 하나의 host 아래 path로 묶는 방식은 [ADR-0009](ADR-0009-container-handles-public-mcp-path.md)이 소유한다. OpenShift Route가 원래 path를 유지한 채 각각의 독립 배포로 연결하므로 이 ADR의 1:1 결정은 그대로 유지된다. diff --git a/docs/decisions/ADR-0009-container-handles-public-mcp-path.md b/docs/decisions/ADR-0009-container-handles-public-mcp-path.md index beb9407..b1cbb06 100644 --- a/docs/decisions/ADR-0009-container-handles-public-mcp-path.md +++ b/docs/decisions/ADR-0009-container-handles-public-mcp-path.md @@ -3,7 +3,7 @@ - 상태: Accepted - 결정일: 2026-08-05 - 대체: [ADR-0008](ADR-0008-shared-host-path-routing.md) -- 부분 대체됨: 결정 4는 [ADR-0010](ADR-0010-portal-owns-route-and-endpoint-registry.md)이 대체한다 +- 부분 대체됨: 결정 4는 [ADR-0013](ADR-0013-portal-owns-route-and-endpoint-registry.md)이 대체한다 - 관련: [ADR-0007](ADR-0007-one-mcp-per-tool-service.md) ## 배경 diff --git a/docs/decisions/ADR-0010-portal-owns-route-and-endpoint-registry.md b/docs/decisions/ADR-0013-portal-owns-route-and-endpoint-registry.md similarity index 99% rename from docs/decisions/ADR-0010-portal-owns-route-and-endpoint-registry.md rename to docs/decisions/ADR-0013-portal-owns-route-and-endpoint-registry.md index b18b4bb..7e744bc 100644 --- a/docs/decisions/ADR-0010-portal-owns-route-and-endpoint-registry.md +++ b/docs/decisions/ADR-0013-portal-owns-route-and-endpoint-registry.md @@ -1,4 +1,4 @@ -# ADR-0010 Tool Server endpoint 목록과 route 매핑의 원천은 Portal이 소유한다 +# ADR-0013 Tool Server endpoint 목록과 route 매핑의 원천은 Portal이 소유한다 - 상태: Accepted - 결정일: 2026-08-16 diff --git a/docs/decisions/README.md b/docs/decisions/README.md index f8f4d9d..0514b79 100644 --- a/docs/decisions/README.md +++ b/docs/decisions/README.md @@ -21,6 +21,6 @@ | [ADR-0007](ADR-0007-one-mcp-per-tool-service.md) | MCP 배포 하나는 Tool Service 하나만 본다 | Superseded | | [ADR-0008](ADR-0008-shared-host-path-routing.md) | 공유 host의 path를 독립 MCP 배포로 연결 | Superseded | | [ADR-0009](ADR-0009-container-handles-public-mcp-path.md) | 컨테이너가 공개 MCP path를 직접 처리 | Accepted | -| [ADR-0010](ADR-0010-portal-owns-route-and-endpoint-registry.md) | Tool Server endpoint 목록과 route 매핑의 원천은 Portal | Accepted | | [ADR-0011](ADR-0011-tool-input-schema-stays-in-document.md) | Tool inputSchema는 문서 밖을 참조하지 않는다 | Accepted | | [ADR-0012](ADR-0012-tool-input-schema-pattern-budget.md) | Tool inputSchema의 정규식에 예산을 둔다 | Accepted | +| [ADR-0013](ADR-0013-portal-owns-route-and-endpoint-registry.md) | Tool Server endpoint 목록과 route 매핑의 원천은 Portal | Accepted | diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 1e28095..0958b84 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -85,7 +85,7 @@ mcp: max-tool-timeout-millis: 30000 portal: enabled: ${MCP_PORTAL_ENABLED:false} - # route key는 설정이 아니라 요청 URI의 /mcp/{routeKey}에서만 결정된다(ADR-0010). + # route key는 설정이 아니라 요청 URI의 /mcp/{routeKey}에서만 결정된다(ADR-0013). # 기본 route로 보정하면 잘못된 단일 진입점 호출이 조용히 성공하므로 여기에 두지 않는다. registry-url: ${MCP_PORTAL_REGISTRY_URL:} refresh-interval-seconds: ${MCP_PORTAL_REFRESH_INTERVAL_SECONDS:300}