All checks were successful
Deploy Gateway / deploy (push) Successful in 2m52s
계약 테스트는 docs/contracts 아래 예제를 golden example로 읽는다.
docs/와 README.md가 ignore되어 있어 예제 파일이 사라졌고 9건이
실패하고 있었다. 문서가 온전했던 마지막 상태(3de052a)에서 복원하고
.gitignore에서 두 항목을 제거한다. 에이전트 산출물인
docs/superpowers/ 제외는 유지한다.
initialize 응답의 capabilities.tools.listChanged를 문서는 true로
적고 있었으나 InitializeHandler는 false를 낸다. 현재 HTTP 단발 응답
transport가 notification을 push할 수 없으므로 false가 맞다. 예제와
architecture.md를 코드에 맞추고, ToolListChangedEvent가 발행되지만
아직 소비되지 않는다는 점과 SSE 도입 시 true로 바꾼다는 조건을
남긴다.
169개 테스트 전부 통과.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
8.7 KiB
8.7 KiB
미합의 항목과 확장 포인트
이 문서는 아직 결정되지 않았거나 운영 적용 전에 보완할 내용만 관리한다. 현재 동작 설명은 architecture.md, Agent Builder wire 계약은 v0.3, Tool Service wire 계약은 bundle 조회 v0.2가 정본이다.
결정이 끝난 항목은 ADR 또는 현재 계약으로 옮기고 이 목록에서 제거한다. 목표안인 Agent Builder-MCP v1 기준선은 전체 payload가 승인되기 전까지 구현 근거가 아니다.
Agent Builder와 합의할 항목
- 여러 MCP protocol version 공존 시 fallback·upgrade와 공지 정책
- Tool name 변경·폐기 시 구·신 이름의 rolling 호환 기간과 Agent 재등록 정책
- Agent Builder가
tools/list를 다시 읽는 주기. 주기적으로 읽는다는 것까지는 확인됐고 값은 미정이다. Agent Builder는 MCP 등록 시점에 Tool 정보를 자기 DB에 저장해 계속 사용하므로, Tool 변경이 실제로 반영되기까지 걸리는 시간은 MCP의 매니페스트 갱신 주기 + Agent Builder의 조회 주기다. 두 값을 각자 정하면 합이 얼마인지 아무도 모르게 되므로 함께 정한다 - Agent Builder 내부 UID와 표준 MCP
name의 lifecycle. UID는 MCP wire 계약에 포함하지 않음 - Agent별 최대 50개 Tool 선별 로직과 권한 거부 시 Agent Builder가 사용자에게 보일 응답
- client disconnect 시 downstream cancellation 계약. 현재 MCP는 이미 시작한 Tool 호출을 취소하지 않는다 (계층별 budget 배분은 architecture.md의 요청 시간 예산에서 확정)
- Tool 원본 오류·업무 코드·PII를 Agent Builder에 노출하거나 마스킹하는 기준
- response 크기, pagination/continuation과 대용량 결과 정책
- retry가 같은 업무 요청인지 판별하는 규칙과
guid재사용 여부. 같은guid를 재사용하기로 합의한 뒤에만 Tool Service의 멱등성 키로 사용 employee-no·virtual-employee-no가 둘 다 없는 요청을 Agent Builder가 보낼 수 있는지, 언젠가 필수로 승격할지- 주기
tools/list가 실패했을 때 DB의 Tool 정보를 어떻게 처리하는가. 직전 목록을 유지하는지, 비우는지에 따라 MCP 재기동·배포 중 수십 초 공백이 Agent에 그대로 드러날 수 있다. 중요 등급 MCP의 replica 하한과 PodDisruptionBudget은 이 답과 무관하게 ADR-0007에서 이미 강제하지만, 답에 따라 비중요 등급의 배포 방식도 달라진다 - 같은 환경 host의 여러 공개 path를 Agent Builder에 등록·변경·폐기하는 절차와 주체. path 처리는 ADR-0009로 확정했지만, 배포 수가 Tool Service 수와 같아 10~20개 이상일 때의 등록 자동화는 미정이다
인증 주체는 ADR-0006에서 확정했다. MCP는 인증·인가를 하지 않는다.
Tool Service와 합의할 항목
GET {manifestUrl}제공, 인증 방식과 NetworkPolicy 범위- Tool name namespace, 변경·폐기 절차와 하위 호환 기간
- 허용할 JSON Schema 2020-12 keyword, 원격
$ref와format정책 - Tool별 timeout, 권한 scope, write Tool의 idempotency 보장
outputSchema/structuredContent도입 여부와 응답 검증 실패 의미- 매니페스트 revision·ETag/304 및 즉시 refresh 알림의 필요성
- 사원 식별자 검증 방식: KMS 키 배포 범위(위조 방지 가능 여부), 동일 암호문 재사용 허용 여부, 만료·nonce 도입 여부. ADR-0006 전제 2가 이 항목에 의존한다
- Tool 이름의 전역 유일성 보장 방법. 등급으로 나뉜 두 Tool Service가 같은 업무
namePrefix를 공유하므로 (처리계-중요와처리계-비중요가 모두processing.), 그 안에서 이름이 겹치지 않게 하는 것은 Tool Service 책임이다. MCP는 자기 bundle의 prefix만 검증하며 다른 MCP의 이름을 알지 못한다(ADR-0007) - Tool의 가용성 등급 분류 기준과 변경 절차. 이 문서에서 위험도는 보안 정책이 아니라 중단 시 업무 영향도를 뜻한다. 등급이 바뀌면 그 Tool을 제공하는 MCP endpoint가 바뀌므로 Agent Builder 반영이 필요하다. 자주 바뀌지 않는 값으로 다룰 수 있는지 확인한다
MCP와 Tool Service를 1:1로 묶는 결정은 ADR-0007에서 확정했다.
현재 서버는 tools/call 결과를 content[0].text로만 반환한다. structuredContent를 지원하기 전까지 운영 매니페스트에는 outputSchema를 사용하지 않는다.
플랫폼·DevOps와 확인할 항목
배포 정의를 이 저장소가 어디까지 소유하는지 확정되지 않았다. 현재는 Helm Chart만 두고 있으며, 빌드·배포 실행 방식은 정의하지 않는다.
- Helm Chart를 어디에 두는가. 앱 저장소인가 배포 전용 저장소인가
- 환경별 namespace 명명 규칙과 Agent Builder namespace. 후자는 Route를 우회한 Pod 직접 접근의 허용 출처이므로 ADR-0006의 전제와 직결된다
- 사내 Nexus에
io.modelcontextprotocol.sdk:mcp-json-jackson2:2.0.0과 Spring Boot 3.5.11가 있는가. 없으면 라이브러리 반입이 선행되어야 한다 - 사내 registry의 JDK 21 빌드·실행 이미지 이름. 현재
Dockerfile은 외부 이미지를 쓴다 - 소스 개행 표준(CRLF)과
gradlew의 관계. shell script가 CRLF이면 Linux 컨테이너에서 실행되지 않으므로 예외 또는 우회 방식이 필요하다 - 환경별 실제
global.mcpHost, 인증서와 TLS termination 책임 - Agent Builder의 실제 고정 egress CIDR과 Route
ip_allowlist값 - 대상 OpenShift의 ingress namespace label과 IngressController endpoint publishing 방식이 Chart의 NetworkPolicy 전제와 맞는지
운영 적용 전 필수 보완
| 영역 | 현재 상태 | 필요한 결정·구현 |
|---|---|---|
| egress | 절대 HTTP(S) 여부만 검증 | host allowlist, redirect·DNS rebinding 방어, mTLS/NetworkPolicy |
| 장애 격리 | timeout과 last-good 제공 | 측정 후 bulkhead·circuit breaker·제한적 retry 결정 |
| 관측성 | 경계 로그와 bundle Actuator 제공 | Micrometer/OpenTelemetry/SIEM 지표와 경보 기준 |
| 감사 | 일반 애플리케이션 로그만 제공 | 보존 대상·기간·암호화·위변조 방지·유실 정책 확정 후 durable sink |
| 용량 | request body 1 MiB 제한 | response 크기, JSON depth, 동시 실행 수, connection pool 부하 기준 |
| Redis | 요청 경로 밖의 선택 cache. Tool snapshot cache는 route별 key(key-prefix:identity:v2:route:{routeToken})로 분리하고, Portal registry fallback key와도 분리한다. Portal registry fallback key 기본값은 axhub:mcp:portal-registry이며 운영에서는 mcp.redis.portal-registry-key로 포털 저장 key와 반드시 맞춘다. |
Redis 사용 여부, key namespace·schema version·TTL·공유 범위, TLS/ACL, Sentinel/Cluster, rolling upgrade 정책 |
| 종료 | Spring graceful shutdown | 신규 요청 차단과 진행 중 Tool 호출 drain 검증 |
| 가용성 | test·prod critical의 replica·PDB·노드 분산 values를 정적 테스트가 검사하고 usable snapshot으로 readiness 판정. 공개 Route도 배포마다 분리 | helm lint/template, 노드 분산 실제 확인, 배포 창 분리, 쿼터 산정. 공유 ingress·DNS 장애는 path 분할로 막히지 않는다 |
코드 확장 경계
- 새 MCP method:
McpMethodHandlerRegistry.Handler구현 하나를 추가하고 SDK method 상수를 사용한다. - Tool metadata: 새 원천을 만들지 말고 local fixture 또는 Tool Service 매니페스트 계약을 확장한다.
- Tool protocol: 실제 두 번째 protocol이 필요할 때만
ToolClient구현을 추가한다. - 인증: 추가하지 않는다. 필요가 생기면 ADR-0006을 대체하는 ADR을 먼저 쓴다.
- 규제 감사: 저장·전달 보장이 합의된 뒤 HTTP/Tool 경계에 durable sink를 연결한다.
새 interface, mapper, DTO, cache 계층은 현재 경계로 해결할 수 없는 요구가 확인되기 전에는 추가하지 않는다.